1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
"""
Django supports parsing the content of an HTTP request, but only for form POST requests.
That behavior is sufficient for dealing with standard HTML forms, but it doesn't map well
to general HTTP requests.
We need a method to be able to:
1.) Determine the parsed content on a request for methods other than POST (eg typically also PUT)
2.) Determine the parsed content on a request for media types other than application/x-www-form-urlencoded
and multipart/form-data. (eg also handle multipart/json)
"""
from django.http import QueryDict
from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser
from django.http.multipartparser import MultiPartParserError
from django.utils import simplejson as json
from rest_framework.compat import yaml, ETParseError
from rest_framework.exceptions import ParseError
from xml.etree import ElementTree as ET
from xml.parsers.expat import ExpatError
import datetime
import decimal
from io import BytesIO
class DataAndFiles(object):
def __init__(self, data, files):
self.data = data
self.files = files
class BaseParser(object):
"""
All parsers should extend `BaseParser`, specifying a `media_type`
attribute, and overriding the `.parse_stream()` method.
"""
media_type = None
def parse(self, string_or_stream, parser_context=None):
"""
The main entry point to parsers. This is a light wrapper around
`parse_stream`, that instead handles both string and stream objects.
"""
if isinstance(string_or_stream, basestring):
stream = BytesIO(string_or_stream)
else:
stream = string_or_stream
return self.parse_stream(stream, parser_context)
def parse_stream(self, stream, parser_context=None):
"""
Given a stream to read from, return the deserialized output.
Should return parsed data, or a DataAndFiles object consisting of the
parsed data and files.
"""
raise NotImplementedError(".parse_stream() must be overridden.")
class JSONParser(BaseParser):
"""
Parses JSON-serialized data.
"""
media_type = 'application/json'
def parse_stream(self, stream, parser_context=None):
"""
Returns a 2-tuple of `(data, files)`.
`data` will be an object which is the parsed content of the response.
`files` will always be `None`.
"""
try:
return json.load(stream)
except ValueError, exc:
raise ParseError('JSON parse error - %s' % unicode(exc))
class YAMLParser(BaseParser):
"""
Parses YAML-serialized data.
"""
media_type = 'application/yaml'
def parse_stream(self, stream, parser_context=None):
"""
Returns a 2-tuple of `(data, files)`.
`data` will be an object which is the parsed content of the response.
`files` will always be `None`.
"""
try:
return yaml.safe_load(stream)
except (ValueError, yaml.parser.ParserError), exc:
raise ParseError('YAML parse error - %s' % LexerTest = TestCase('LexerTest');
LexerTest.prototype.testTokenizeAString = function(){
var lexer = new Lexer("a.bc[22]+1.3|f:'a\\\'c':\"d\\\"e\"");
var tokens = lexer.parse();
var i = 0;
assertEquals(tokens[i].index, 0);
assertEquals(tokens[i].text, 'a.bc');
i++;
assertEquals(tokens[i].index, 4);
assertEquals(tokens[i].text, '[');
i++;
assertEquals(tokens[i].index, 5);
assertEquals(tokens[i].text, 22);
i++;
assertEquals(tokens[i].index, 7);
assertEquals(tokens[i].text, ']');
i++;
assertEquals(tokens[i].index, 8);
assertEquals(tokens[i].text, '+');
i++;
assertEquals(tokens[i].index, 9);
assertEquals(tokens[i].text, 1.3);
i++;
assertEquals(tokens[i].index, 12);
assertEquals(tokens[i].text, '|');
i++;
assertEquals(tokens[i].index, 13);
assertEquals(tokens[i].text, 'f');
i++;
assertEquals(tokens[i].index, 14);
assertEquals(tokens[i].text, ':');
i++;
assertEquals(tokens[i].index, 15);
assertEquals(tokens[i].string, "a'c");
i++;
assertEquals(tokens[i].index, 21);
assertEquals(tokens[i].text, ':');
i++;
assertEquals(tokens[i].index, 22);
assertEquals(tokens[i].string, 'd"e');
};
LexerTest.prototype.testTokenizeUndefined = function(){
var lexer = new Lexer("undefined");
var tokens = lexer.parse();
var i = 0;
assertEquals(tokens[i].index, 0);
assertEquals(tokens[i].text, 'undefined');
assertEquals(undefined, tokens[i].fn());
};
LexerTest.prototype.testTokenizeRegExp = function(){
var lexer = new Lexer("/r 1/");
var tokens = lexer.parse();
var i = 0;
assertEquals(tokens[i].index, 0);
assertEquals(tokens[i].text, 'r 1');
assertEquals("r 1".match(tokens[i].fn())[0], 'r 1');
};
LexerTest.prototype.testQuotedString = function(){
var str = "['\\'', \"\\\"\"]";
var lexer = new Lexer(str);
var tokens = lexer.parse();
assertEquals(1, tokens[1].index);
assertEquals("'", tokens[1].string);
assertEquals(7, tokens[3].index);
assertEquals('"', tokens[3].string);
};
LexerTest.prototype.testQuotedStringEscape = function(){
var str = '"\\"\\n\\f\\r\\t\\v\\u00A0"';
var lexer = new Lexer(str);
var tokens = lexer.parse();
assertEquals('"\n\f\r\t\v\u00A0', tokens[0].string);
};
LexerTest.prototype.testTokenizeUnicode = function(){
var lexer = new Lexer('"\\u00A0"');
var tokens = lexer.parse();
assertEquals(1, tokens.length);
assertEquals('\u00a0', tokens[0].string);
};
LexerTest.prototype.testTokenizeRegExpWithOptions = function(){
var lexer = new Lexer("/r/g");
var tokens = lexer.parse();
var i = 0;
assertEquals(tokens[i].index, 0);
assertEquals(tokens[i].text, 'r');
assertEquals(tokens[i].flags, 'g');
assertEquals("rr".match(tokens[i].fn()).length, 2);
};
LexerTest.prototype.testTokenizeRegExpWithEscape = function(){
var lexer = new Lexer("/\\/\\d/");
var tokens = lexer.parse();
var i = 0;
assertEquals(tokens[i].index, 0);
assertEquals(tokens[i].text, '\\/\\d');
assertEquals("/1".match(tokens[i].fn())[0], '/1');
};
LexerTest.prototype.testIgnoreWhitespace = function(){
var lexer = new Lexer("a \t \n \r b");
var tokens = lexer.parse();
assertEquals(tokens[0].text, 'a');
assertEquals(tokens[1].text, 'b');
};
LexerTest.prototype.testRelation = function(){
var lexer = new Lexer("! == != < > <= >=");
var tokens = lexer.parse();
assertEquals(tokens[0].text, '!');
assertEquals(tokens[1].text, '==');
assertEquals(tokens[2].text, '!=');
assertEquals(tokens[3].text, '<');
assertEquals(tokens[4].text, '>');
assertEquals(tokens[5].text, '<=');
assertEquals(tokens[6].text, '>=');
};
LexerTest.prototype.testStatements = function(){
var lexer = new Lexer("a;b;");
var tokens = lexer.parse();
assertEquals(tokens[0].text, 'a');
assertEquals(tokens[1].text, ';');
assertEquals(tokens[2].text, 'b');
assertEquals(tokens[3].text, ';');
};
ParserTest = TestCase('ParserTest');
ParserTest.prototype.testExpressions = function(){
var scope = createScope();
assertEquals(scope.$eval("-1"), -1);
assertEquals(scope.$eval("1 + 2.5"), 3.5);
assertEquals(scope.$eval("1 + -2.5"), -1.5);
assertEquals(scope.$eval("1+2*3/4"), 1+2*3/4);
assertEquals(scope.$eval("0--1+1.5"), 0- -1 + 1.5);
assertEquals(scope.$eval("-0--1++2*-3/-4"), -0- -1+ +2*-3/-4);
assertEquals(scope.$eval("1/2*3"), 1/2*3);
};
ParserTest.prototype.testComparison = function(){
var scope = createScope();
assertEquals(scope.$eval("false"), false);
assertEquals(scope.$eval("!true"), false);
assertEquals(scope.$eval("1==1"), true);
assertEquals(scope.$eval("1!=2"), true);
assertEquals(scope.$eval("1<2"), true);
assertEquals(scope.$eval("1<=1"), true);
assertEquals(scope.$eval("1>2"), 1>2);
assertEquals(scope.$eval("2>=1"), 2>=1);
assertEquals(true === 2<3, scope.$eval("true==2<3"));
};
ParserTest.prototype.testLogical = function(){
var scope = createScope();
assertEquals(scope.$eval("0&&2"), 0&&2);
assertEquals(scope.$eval("0||2"), 0||2);
assertEquals(scope.$eval("0||1&&2"), 0||1&&2);
};
ParserTest.prototype.testString = function(){
var scope = createScope();
assertEquals(scope.$eval("'a' + 'b c'"), "ab c");
};
ParserTest.prototype.testFilters = function(){
angular.filter.substring = function(input, start, end) {
return input.substring(start, end);
};
angular.filter.upper = {_case:function(input) {
return input.toUpperCase();
}};
var scope = createScope();
try {
scope.$eval("1|nonExistant");
fail();
} catch (e) {
assertEquals(e, "Function 'nonExistant' at column '3' in '1|nonExistant' is not defined.");
}
scope.$set('offset', 3);
assertEquals(scope.$eval("'abcd'|upper._case"), "ABCD");
assertEquals(scope.$eval("'abcd'|substring:1:offset"), "bc");
assertEquals(scope.$eval("'abcd'|substring:1:3|upper._case"), "BC");
};
ParserTest.prototype.testScopeAccess = function(){
var scope = createScope();
scope.$set('a', 123);
scope.$set('b.c', 456);
assertEquals(scope.$eval("a", scope), 123);
assertEquals(scope.$eval("b.c", scope), 456);
assertEquals(scope.$eval("x.y.z", scope), undefined);
};
ParserTest.prototype.testGrouping = function(){
var scope = createScope();
assertEquals(scope.$eval("(1+2)*3"), (1+2)*3);
};
ParserTest.prototype.testAssignments = function(){
var scope = createScope();
assertEquals(scope.$eval("a=12"), 12);
assertEquals(scope.$get("a"), 12);
scope = createScope();
assertEquals(scope.$eval("x.y.z=123;"), 123);
assertEquals(scope.$get("x.y.z"), 123);
assertEquals(234, scope.$eval("a=123; b=234"));
assertEquals(123, scope.$get("a"));
assertEquals(234, scope.$get("b"));
};
ParserTest.prototype.testFunctionCallsNoArgs = function(){
var scope = createScope();
scope.$set('const', function(a,b){return 123;});
assertEquals(scope.$eval("const()"), 123);
};
ParserTest.prototype.testFunctionCalls = function(){
var scope = createScope();
scope.$set('add', function(a,b){
return a+b;
});
assertEquals(3, scope.$eval("add(1,2)"));
};
ParserTest.prototype.testCalculationBug = function(){
var scope = createScope();
scope.$set('taxRate', 8);
scope.$set('subTotal', 100);
assertEquals(scope.$eval("taxRate / 100 * subTotal"), 8);
assertEquals(scope.$eval("subTotal * taxRate / 100"), 8);
};
ParserTest.prototype.testArray = function(){
var scope = createScope();
assertEquals(scope.$eval("[]").length, 0);
assertEquals(scope.$eval("[1, 2]").length, 2);
assertEquals(scope.$eval("[1, 2]")[0], 1);
assertEquals(scope.$eval("[1, 2]")[1], 2);
};
ParserTest.prototype.testArrayAccess = function(){
var scope = createScope();
assertEquals(scope.$eval("[1][0]"), 1);
assertEquals(scope.$eval("[[1]][0][0]"), 1);
assertEquals(scope.$eval("[].length"), 0);
assertEquals(scope.$eval("[1, 2].length"), 2);
};
ParserTest.prototype.testObject = function(){
var scope = createScope();
assertEquals(toJson(scope.$eval("{}")), "{}");
assertEquals(toJson(scope.$eval("{a:'b'}")), '{"a":"b"}');
assertEquals(toJson(scope.$eval("{'a':'b'}")), '{"a":"b"}');
assertEquals(toJson(scope.$eval("{\"a\":'b'}")), '{"a":"b"}');
};
ParserTest.prototype.testObjectAccess = function(){
var scope = createScope();
assertEquals("WC", scope.$eval("{false:'WC', true:'CC'}[false]"));
};
ParserTest.prototype.testJSON = function(){
var scope = createScope();
assertEquals(toJson(scope.$eval("[{}]")), "[{}]");
assertEquals(toJson(scope.$eval("[{a:[]}, {b:1}]")), '[{"a":[]},{"b":1}]');
};
ParserTest.prototype.testMultippleStatements = function(){
var scope = createScope();
assertEquals(scope.$eval("a=1;b=3;a+b"), 4);
assertEquals(scope.$eval(";;1;;"), 1);
};
ParserTest.prototype.testParseThrow = function(){
expectAsserts(1);
var scope = createScope();
scope.$set('e', 'abc');
try {
scope.$eval("throw e");
} catch(e) {
assertEquals(e, 'abc');
}
};
ParserTest.prototype.testMethodsGetDispatchedWithCorrectThis = function(){
var scope = createScope();
var C = function (){
this.a=123;
};
C.prototype.getA = function(){
return this.a;
};
scope.$set("obj", new C());
assertEquals(123, scope.$eval("obj.getA()"));
};
ParserTest.prototype.testMethodsArgumentsGetCorrectThis = function(){
var scope = createScope();
var C = function (){
this.a=123;
};
C.prototype.sum = function(value){
return this.a + value;
};
C.prototype.getA = function(){
return this.a;
};
scope.$set("obj", new C());
assertEquals(246, scope.$eval("obj.sum(obj.getA())"));
};
ParserTest.prototype.testObjectPointsToScopeValue = function(){
var scope = createScope();
scope.$set('a', "abc");
assertEquals("abc", scope.$eval("{a:a}").a);
};
ParserTest.prototype.testFieldAccess = function(){
var scope = createScope();
var fn = function(){
return {name:'misko'};
};
scope.$set('a', fn);
assertEquals("misko", scope.$eval("a().name"));
};
ParserTest.prototype.testArrayIndexBug = function () {
var scope = createScope();
scope.$set('items', [{}, {name:'misko'}]);
assertEquals("misko", scope.$eval('items[1].name'));
};
ParserTest.prototype.testArrayAssignment = function () {
var scope = createScope();
scope.$set('items', []);
assertEquals("abc", scope.$eval('items[1] = "abc"'));
assertEquals("abc", scope.$eval('items[1]'));
// Dont know how to make this work....
// assertEquals("moby", scope.$eval('books[1] = "moby"'));
// assertEquals("moby", scope.$eval('books[1]'));
};
ParserTest.prototype.testFiltersCanBeGrouped = function () {
var scope = createScope({name:'MISKO'});
assertEquals('misko', scope.$eval('n = (name|lowercase)'));
assertEquals('misko', scope.$eval('n'));
};
ParserTest.prototype.testFiltersCanBeGrouped = function () {
var scope = createScope({name:'MISKO'});
assertEquals('misko', scope.$eval('n = (name|lowercase)'));
assertEquals('misko', scope.$eval('n'));
};
ParserTest.prototype.testRemainder = function () {
var scope = createScope();
assertEquals(1, scope.$eval('1%2'));
};
ParserTest.prototype.testSumOfUndefinedIsNotUndefined = function () {
var scope = createScope();
assertEquals(1, scope.$eval('1+undefined'));
assertEquals(1, scope.$eval('undefined+1'));
};
ParserTest.prototype.testMissingThrowsError = function() {
var scope = createScope();
try {
scope.$eval('[].count(');
fail();
} catch (e) {
assertEquals('Unexpected end of expression: [].count(', e);
}
};
ParserTest.prototype.XtestItShouldParseOnChangeIntoHashSet = function () {
var scope = createScope({count:0});
scope.watch("$anchor.a:count=count+1;$anchor.a:count=count+20;b:count=count+300");
scope.watchListeners["$anchor.a"].listeners[0]();
assertEquals(1, scope.$get("count"));
scope.watchListeners["$anchor.a"].listeners[1]();
assertEquals(21, scope.$get("count"));
scope.watchListeners["b"].listeners[0]({scope:scope});
assertEquals(321, scope.$get("count"));
};
ParserTest.prototype.XtestItShouldParseOnChangeBlockIntoHashSet = function () {
var scope = createScope({count:0});
var listeners = {a:[], b:[]};
scope.watch("a:{count=count+1;count=count+20;};b:count=count+300",
function(n, fn){listeners[n].push(fn);});
assertEquals(1, scope.watchListeners.a.listeners.length);
assertEquals(1, scope.watchListeners.b.listeners.length);
scope.watchListeners["a"].listeners[0]();
assertEquals(21, scope.$get("count"));
scope.watchListeners["b"].listeners[0]();
assertEquals(321, scope.$get("count"));
};
ParserTest.prototype.XtestItShouldParseEmptyOnChangeAsNoop = function () {
var scope = createScope();
scope.watch("", function(){fail();});
};
ParserTest.prototype.testItShouldCreateClosureFunctionWithNoArguments = function () {
var scope = createScope();
var fn = scope.$eval("{:value}");
scope.$set("value", 1);
assertEquals(1, fn());
scope.$set("value", 2);
assertEquals(2, fn());
fn = scope.$eval("{():value}");
assertEquals(2, fn());
};
ParserTest.prototype.testItShouldCreateClosureFunctionWithArguments = function () {
var scope = createScope();
scope.$set("value", 1);
var fn = scope.$eval("{(a):value+a}");
assertEquals(11, fn(10));
scope.$set("value", 2);
assertEquals(12, fn(10));
fn = scope.$eval("{(a,b):value+a+b}");
assertEquals(112, fn(10, 100));
};
ParserTest.prototype.testItShouldHaveDefaultArugument = function(){
var scope = createScope();
var fn = scope.$eval("{:$*2}");
assertEquals(4, fn(2));
};
ParserTest.prototype.XtestReturnFunctionsAreNotBound = function(){
var scope = createScope();
scope.entity("Group", new DataStore());
var Group = scope.$get("Group");
assertEquals("eval Group", "function", typeof scope.$eval("Group"));
assertEquals("direct Group", "function", typeof Group);
assertEquals("eval Group.all", "function", typeof scope.$eval("Group.query"));
assertEquals("direct Group.all", "function", typeof Group.query);
};
ParserTest.prototype.testDoubleNegationBug = function (){
var scope = createScope();
assertEquals(true, scope.$eval('true'));
assertEquals(false, scope.$eval('!true'));
assertEquals(true, scope.$eval('!!true'));
assertEquals('a', scope.$eval('{true:"a", false:"b"}[!!true]'));
};
ParserTest.prototype.testNegationBug = function () {
var scope = createScope();
assertEquals(!false || true, scope.$eval("!false || true"));
assertEquals(!11 == 10, scope.$eval("!11 == 10"));
assertEquals(12/6/2, scope.$eval("12/6/2"));
};
ParserTest.prototype.testBugStringConfusesParser = function() {
var scope = createScope();
assertEquals('!', scope.$eval('suffix = "!"'));
};
ParserTest.prototype.testParsingBug = function () {
var scope = createScope();
assertEquals({a: "-"}, scope.$eval("{a:'-'}"));
};
ParserTest.prototype.testUndefined = function () {
var scope = createScope();
assertEquals(undefined, scope.$eval("undefined"));
assertEquals(undefined, scope.$eval("a=undefined"));
assertEquals(undefined, scope.$get("a"));
};
|