validator.nu 0.0.2 → 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.
@@ -6,12 +6,24 @@ ruby client library for the validator.nu HTML5 validation API
6
6
 
7
7
  gem install validator.nu
8
8
  require 'validator.nu'
9
- Validator.nu("http://google.com")
10
-
9
+ Validator.nu('http://bbc.co.uk')
10
+
11
+ # If you want to use a private version of the validator.nu application
12
+ Validator.nu('http://bbc.co.uk', :host => 'validator.mine.com', :port => 8808)
13
+
14
+
15
+ # or you can send a document to validate to the service directly
16
+ Validator.nu( document )
17
+
18
+ # or even, with gzip compression
19
+ Validator.nu( document, :gzip => true )
20
+
21
+ # it's a good idea to send the original content type and character encoding. The default is 'text/html; charset=utf-8'
22
+ Validator.nu( document, :content_type => 'text/html; charset=utf-8' )
23
+
24
+
11
25
  == Todo
12
26
 
13
- * implement POST html document functionality of the API
14
- * transmit compressed data
15
27
  * output pure JSON ?
16
28
 
17
29
  == Note on Patches/Pull Requests
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -2,6 +2,8 @@ $:.unshift File.dirname(__FILE__)
2
2
 
3
3
  require 'net/http'
4
4
  require 'cgi'
5
+ require 'uri'
6
+ require 'zlib'
5
7
 
6
8
  module Validator
7
9
 
@@ -37,11 +39,24 @@ module Validator
37
39
  class << self
38
40
  class RemoteException < StandardError; end;
39
41
 
42
+ CONTENT_ENCODING = "UTF-8"
43
+ CONTENT_TYPE = "text/html; charset=utf-8"
40
44
  HOST = "validator.nu"
41
- PORT = 80
45
+ GZIP = false
46
+ PORT = 80
42
47
 
43
48
  def nu(url_or_document, options={})
44
- get(url_or_document, options)
49
+ begin
50
+ uri = URI.parse(url_or_document)
51
+
52
+ if uri.class == URI::Generic
53
+ post(url_or_document, options)
54
+ else
55
+ get(url_or_document, options)
56
+ end
57
+ rescue URI::InvalidURIError
58
+ post(url_or_document, options)
59
+ end
45
60
  end
46
61
 
47
62
 
@@ -56,7 +71,6 @@ module Validator
56
71
  host = options[:host] || HOST
57
72
  port = options[:port] || PORT
58
73
  http = Net::HTTP.new(host, port)
59
- STDERR.puts host
60
74
  uri = "/?&doc=#{CGI::escape(url)}&out=json"
61
75
 
62
76
  response = http.start do |http|
@@ -77,6 +91,45 @@ module Validator
77
91
  end
78
92
  end
79
93
 
94
+ def post(document, options)
95
+ begin
96
+ host = options[:host] || HOST
97
+ port = options[:port] || PORT
98
+ content_type = options[:content_type] || CONTENT_TYPE
99
+ content_encoding = options[:content_encoding] || CONTENT_ENCODING
100
+ gzip = options[:gzip] || GZIP
101
+
102
+ if gzip
103
+ content_encoding = 'gzip'
104
+ output = StringIO.new
105
+ gz = Zlib::GzipWriter.new(output)
106
+ gz.write(document)
107
+ gz.close
108
+ document = output.string
109
+ end
110
+
111
+ http = Net::HTTP.new(host, port)
112
+ uri = "/?out=json"
113
+ headers = { 'Content-Type' => content_type, 'Content-Encoding' => content_encoding }
114
+
115
+ response = http.start do |http|
116
+ http.post(uri, document, headers)
117
+ end
118
+
119
+ if response.kind_of? Net::HTTPSuccess
120
+ return response.body
121
+ else
122
+ STDERR.puts response.body.inspect
123
+ raise RemoteException.new("#{response.code}: #{response.message}")
124
+ end
125
+
126
+ rescue Exception => e
127
+ STDERR.puts "Error contacting validator.nu: #{e}"
128
+ STDERR.puts e.backtrace.join("\n"), 'debug'
129
+ raise e
130
+ end
131
+ end
132
+
80
133
  end
81
134
 
82
135
  end
@@ -0,0 +1 @@
1
+ {"messages":[{"type":"info","message":"The Content-Type was “application/xhtml+xml”. Using the XML parser (not resolving external entities)."},{"type":"info","message":"Using the preset for XHTML5+ARIA, SVG 1.1 plus MathML 2.0 (experimental) based on the root namespace."},{"type":"error","lastLine":6,"lastColumn":10,"subType":"fatal","message":"name expected","extract":"body>\n<p>Fatal & erro","hiliteStart":15,"hiliteLength":1}]}
@@ -0,0 +1,9 @@
1
+ <html xmlns="http://www.w3.org/1999/xhtml">
2
+ <head>
3
+ <title>Fatal error</title>
4
+ </head>
5
+ <body>
6
+ <p>Fatal & error</p>
7
+ </body>
8
+ </html>
9
+
@@ -0,0 +1 @@
1
+ {"messages":[{"type":"info","message":"The Content-Type was “image/svg+xml”. Using the XML parser (not resolving external entities)."},{"type":"info","message":"Using the preset for SVG 1.1+IRI, XHTML5+ARIA plus MathML 2.0 (experimental) based on the root namespace."}]}
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 100 100'>
2
+ <title>Dispatch on root namespace</title>
3
+ <defs>
4
+ <circle id='thecircle' fill='green' cx='0' cy='0' r='20'/>
5
+ </defs>
6
+ <use xlink:href='#thecircle' x='20' y='20'/>
7
+ <use xlink:href='#thecircle' x='80' y='80'/>
8
+ </svg>
9
+
@@ -0,0 +1 @@
1
+ {"messages":[{"type":"info","message":"The Content-Type was “text/html”. Using the HTML parser."},{"type":"info","message":"Using the schema for HTML5+ARIA (experimental)."}]}
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>No message</title>
5
+ </head>
6
+ <body>
7
+ <p>No message</p>
8
+ </body>
9
+ </html>
10
+
@@ -0,0 +1 @@
1
+ {"messages":[{"type":"non-document-error","subType":"io","message":"HTTP resource not retrievable. The HTTP status from the remote server was: 404."}]}
@@ -0,0 +1 @@
1
+ {"messages":[{"type":"info","message":"The Content-Type was “text/html”. Using the HTML parser."},{"type":"info","message":"Using the schema for HTML5+ARIA (experimental)."},{"type":"error","lastLine":7,"lastColumn":4,"message":"“&” did not start a character reference. (“&” probably should have been escaped as “&amp;”.)","extract":"ead>\n<body>\n<p>&a</p>","hiliteStart":15,"hiliteLength":1}]}
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Tokenizer error</title>
5
+ </head>
6
+ <body>
7
+ <p>&a</p>
8
+ </body>
9
+ </html>
10
+
@@ -0,0 +1 @@
1
+ {"messages":[{"type":"info","message":"The Content-Type was “text/html”. Using the HTML parser."},{"type":"info","message":"Using the schema for HTML5+ARIA (experimental)."},{"type":"error","lastLine":7,"lastColumn":13,"firstColumn":10,"message":"End tag for “p” seen, but there were unclosed elements.","extract":"\n<p><span></p>\n</bod","hiliteStart":10,"hiliteLength":4}]}
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Tree builder error</title>
5
+ </head>
6
+ <body>
7
+ <p><span></p>
8
+ </body>
9
+ </html>
10
+
@@ -0,0 +1 @@
1
+ {"messages":[{"type":"info","message":"The Content-Type was “text/html”. Using the HTML parser."},{"type":"info","message":"Using the schema for HTML5+ARIA (experimental)."},{"type":"error","lastLine":7,"lastColumn":13,"message":"“<” in an unquoted attribute value. Probable cause: Missing “>” immediately before.","extract":"y>\n<p class=foo<bar><","hiliteStart":15,"hiliteLength":1}]}
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Warning</title>
5
+ </head>
6
+ <body>
7
+ <p class=foo<bar></p>
8
+ </body>
9
+ </html>
10
+
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/spec_helper'
4
4
  describe Validator do
5
5
 
6
6
 
7
- describe "Validator.nu" do
7
+ describe "Validator.nu, get -ing" do
8
8
 
9
9
  it "should receive a no message result" do
10
10
  fixture = File.open("#{File.dirname(__FILE__)}/fixtures/no-message.json").read
@@ -65,4 +65,58 @@ describe Validator do
65
65
  end
66
66
 
67
67
  end
68
+
69
+ describe "Validator.nu, post -ing" do
70
+
71
+ it "should receive a no message result" do
72
+ fixture = File.open("#{File.dirname(__FILE__)}/fixtures/no-message-post.json").read
73
+ html_fixture = File.open("#{File.dirname(__FILE__)}/fixtures/no-message.html").read
74
+
75
+ Validator.nu(html_fixture).should == fixture
76
+ end
77
+
78
+ it "should receive an info result" do
79
+ fixture = File.open("#{File.dirname(__FILE__)}/fixtures/info-post.json").read
80
+ html_fixture = File.open("#{File.dirname(__FILE__)}/fixtures/info.svg").read
81
+
82
+ Validator.nu(html_fixture, :content_type => 'image/svg+xml').should == fixture
83
+ end
84
+
85
+ it "should receive a warning result" do
86
+ fixture = File.open("#{File.dirname(__FILE__)}/fixtures/warning-post.json").read
87
+ html_fixture = File.open("#{File.dirname(__FILE__)}/fixtures/warning.html").read
88
+
89
+ Validator.nu(html_fixture).should == fixture
90
+ end
91
+
92
+ it "should receive a precise error result" do
93
+ fixture = File.open("#{File.dirname(__FILE__)}/fixtures/precise-error-post.json").read
94
+ html_fixture = File.open("#{File.dirname(__FILE__)}/fixtures/precise-error.html").read
95
+
96
+ Validator.nu(html_fixture).should == fixture
97
+ end
98
+
99
+ it "should receive a range error result" do
100
+ fixture = File.open("#{File.dirname(__FILE__)}/fixtures/range-error-post.json").read
101
+ html_fixture = File.open("#{File.dirname(__FILE__)}/fixtures/range-error.html").read
102
+
103
+ Validator.nu(html_fixture).should == fixture
104
+ end
105
+
106
+ it "should receive a fatal error result" do
107
+ fixture = File.open("#{File.dirname(__FILE__)}/fixtures/fatal-error-post.json").read
108
+ html_fixture = File.open("#{File.dirname(__FILE__)}/fixtures/fatal-error.html").read
109
+ Validator.nu( html_fixture, :content_type => 'application/xhtml+xml').should == fixture
110
+ end
111
+
112
+ end
113
+
114
+ it "Validator.nu posting with gzip" do
115
+ fixture = File.open("#{File.dirname(__FILE__)}/fixtures/info-post.json").read
116
+ html_fixture = File.open("#{File.dirname(__FILE__)}/fixtures/info.svg").read
117
+
118
+ Validator.nu(html_fixture, :content_type => 'image/svg+xml', :gzip => true).should == fixture
119
+
120
+ end
121
+
68
122
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{validator.nu}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Rice"]
12
- s.date = %q{2010-04-07}
12
+ s.date = %q{2010-04-15}
13
13
  s.description = %q{ruby client library for the validator.nu HTML5 validation API}
14
14
  s.email = %q{me@davidjrice.co.uk}
15
15
  s.extra_rdoc_files = [
@@ -24,12 +24,25 @@ Gem::Specification.new do |s|
24
24
  "Rakefile",
25
25
  "VERSION",
26
26
  "lib/validator.nu.rb",
27
+ "spec/fixtures/fatal-error-post.json",
28
+ "spec/fixtures/fatal-error.html",
27
29
  "spec/fixtures/fatal-error.json",
30
+ "spec/fixtures/info-post.json",
28
31
  "spec/fixtures/info.json",
32
+ "spec/fixtures/info.svg",
33
+ "spec/fixtures/no-message-post.json",
34
+ "spec/fixtures/no-message.html",
29
35
  "spec/fixtures/no-message.json",
36
+ "spec/fixtures/non-document-error-post.json",
30
37
  "spec/fixtures/non-document-error.json",
38
+ "spec/fixtures/precise-error-post.json",
39
+ "spec/fixtures/precise-error.html",
31
40
  "spec/fixtures/precise-error.json",
41
+ "spec/fixtures/range-error-post.json",
42
+ "spec/fixtures/range-error.html",
32
43
  "spec/fixtures/range-error.json",
44
+ "spec/fixtures/warning-post.json",
45
+ "spec/fixtures/warning.html",
33
46
  "spec/fixtures/warning.json",
34
47
  "spec/spec_helper.rb",
35
48
  "spec/validator_spec.rb",
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Rice
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-07 00:00:00 +01:00
17
+ date: 2010-04-15 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -35,12 +35,25 @@ files:
35
35
  - Rakefile
36
36
  - VERSION
37
37
  - lib/validator.nu.rb
38
+ - spec/fixtures/fatal-error-post.json
39
+ - spec/fixtures/fatal-error.html
38
40
  - spec/fixtures/fatal-error.json
41
+ - spec/fixtures/info-post.json
39
42
  - spec/fixtures/info.json
43
+ - spec/fixtures/info.svg
44
+ - spec/fixtures/no-message-post.json
45
+ - spec/fixtures/no-message.html
40
46
  - spec/fixtures/no-message.json
47
+ - spec/fixtures/non-document-error-post.json
41
48
  - spec/fixtures/non-document-error.json
49
+ - spec/fixtures/precise-error-post.json
50
+ - spec/fixtures/precise-error.html
42
51
  - spec/fixtures/precise-error.json
52
+ - spec/fixtures/range-error-post.json
53
+ - spec/fixtures/range-error.html
43
54
  - spec/fixtures/range-error.json
55
+ - spec/fixtures/warning-post.json
56
+ - spec/fixtures/warning.html
44
57
  - spec/fixtures/warning.json
45
58
  - spec/spec_helper.rb
46
59
  - spec/validator_spec.rb