Tests failing + incomplete

This commit is contained in:
regiostech 2016-03-03 22:47:20 -05:00
parent 76af2710af
commit f41f367808
5 changed files with 830 additions and 17 deletions

75
.gitignore vendored
View file

@ -1,27 +1,68 @@
# See https://www.dartlang.org/tools/private-files.html
### VisualStudioCode template
.settings
# Files and directories created by pub
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
/Test Results - Run_All_Tests.html
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Dart template
# Don’t commit the following directories created by pub.
.buildlog
.packages
.project
.pub/
build/
**/packages/
packages
.packages
# Files created by dart2js
# (Most Dart developers will use pub build to compile Dart, use/modify these
# rules if you intend to use dart2js directly
# Convention is to use extension '.dart.js' for Dart compiled to Javascript to
# differentiate from explicit Javascript files)
# Or the files created by dart2js.
*.dart.js
*.part.js
*.js_
*.js.deps
*.js.map
*.info.json
# Directory created by dartdoc
doc/api/
# Don't commit pubspec lock file
# (Library packages only! Remove pattern if developing an application package)
# Include when developing application packages.
pubspec.lock

File diff suppressed because one or more lines are too long

67
lib/body_parser.dart Normal file
View file

@ -0,0 +1,67 @@
// A library for parsing HTTP request bodies and queries.
library body_parser;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:json_god/json_god.dart';
/// A representation of data from an incoming request.
class BodyParseResult {
/// The parsed body.
Map body = {};
/// The parsed query string.
Map query = {};
}
/// Grabs data from an incoming request.
///
/// Supports urlencoded and JSON.
Future<BodyParseResult> parseBody(HttpRequest request) async {
BodyParseResult result = new BodyParseResult();
ContentType contentType = request.headers.contentType;
// Parse body
if (contentType != null) {
if (contentType.mimeType == 'application/json')
result.body = JSON.decode(await request.transform(UTF8.decoder).join());
else if (contentType.mimeType == 'application/x-www-form-urlencoded') {
String body = await request.transform(UTF8.decoder).join();
buildMapFromUri(result.body, body);
}
}
// Parse query
RegExp queryRgx = new RegExp(r'\?(.+)$');
String uriString = request.requestedUri.toString();
if (queryRgx.hasMatch(uriString)) {
Match queryMatch = queryRgx.firstMatch(uriString);
buildMapFromUri(result.query, queryMatch.group(1));
}
return result;
}
/// Parses a URI-encoded string into real data! **Wow!**
buildMapFromUri(Map map, String body) {
God god = new God();
for (String keyValuePair in body.split('&')) {
if (keyValuePair.contains('=')) {
List<String> split = keyValuePair.split('=');
String key = Uri.decodeQueryComponent(split[0]);
String value = Uri.decodeQueryComponent(split[1]);
num numValue = num.parse(value, (_) => double.NAN);
if (!numValue.isNaN)
map[key] = numValue;
else if (value.startsWith('[') && value.endsWith(']'))
map[key] = god.deserialize(value);
else if (value.startsWith('{') && value.endsWith('}'))
map[key] = god.deserialize(value);
else if (value.trim().toLowerCase() == 'null')
map[key] = null;
else map[key] = value;
} else map[Uri.decodeQueryComponent(keyValuePair)] = true;
}
}

9
pubspec.yaml Normal file
View file

@ -0,0 +1,9 @@
name: body_parser
author: Tobe O <thosakwe@gmail.com>
version: 1.0.0-dev
description: Parse request bodies and query strings in Dart.
dependencies:
json_god: any
dev_dependencies:
http: any
test: any

60
test/all_tests.dart Normal file
View file

@ -0,0 +1,60 @@
import 'dart:io';
import 'package:body_parser/body_parser.dart';
import 'package:http/http.dart' as http;
import 'package:json_god/json_god.dart';
import 'package:test/test.dart';
main() {
group('Test server support', () {
HttpServer server;
String url;
http.Client client;
God god;
setUp(() async {
server = await HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0);
server.listen((HttpRequest request) async {
//Server will simply return a JSON representation of the parsed body
request.response.write(god.serialize(await parseBody(request)));
await request.response.close();
});
url = 'http://localhost:${server.port}';
print('Test server listening on $url');
client = new http.Client();
god = new God();
});
tearDown(() async {
await server.close(force: true);
client.close();
server = null;
url = null;
client = null;
god = null;
});
group('JSON', () {
test('Post Simple JSON', () async {
var response = await client.post(url, body: {
'hello': 'world'
});
expect(response.body, equals('{"body":{"hello":"world"},"query":{}}'));
});
test('Post Complex JSON', () async {
var postData = god.serialize({
'hello': 'world',
'nums': [1, 2.0, 3 - 1],
'map': {
'foo': {
'bar': 'baz'
}
}
});
var response = await client.post(url, body: postData);
var body = god.deserialize(response.body)['body'];
expect(body['hello'], equals('world'));
});
});
});
}