summaryrefslogtreecommitdiffstats
path: root/testing/mozbase/rust/mozprofile/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/mozbase/rust/mozprofile/src/lib.rs241
1 files changed, 241 insertions, 0 deletions
diff --git a/testing/mozbase/rust/mozprofile/src/lib.rs b/testing/mozbase/rust/mozprofile/src/lib.rs
new file mode 100644
index 0000000000..346f291137
--- /dev/null
+++ b/testing/mozbase/rust/mozprofile/src/lib.rs
@@ -0,0 +1,241 @@
+#![forbid(unsafe_code)]
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+extern crate tempfile;
+
+pub mod preferences;
+pub mod prefreader;
+pub mod profile;
+
+#[cfg(test)]
+mod test {
+ // use std::fs::File;
+ // use profile::Profile;
+ use crate::preferences::Pref;
+ use crate::prefreader::{parse, serialize, tokenize};
+ use crate::prefreader::{Position, PrefToken};
+ use std::collections::BTreeMap;
+ use std::io::Cursor;
+ use std::str;
+
+ #[test]
+ fn tokenize_simple() {
+ let prefs = " user_pref ( 'example.pref.string', 'value' ) ;\n \
+ pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false);";
+
+ let p = Position::new();
+
+ let expected = vec![
+ PrefToken::UserPrefFunction(p),
+ PrefToken::Paren('(', p),
+ PrefToken::String("example.pref.string".into(), p),
+ PrefToken::Comma(p),
+ PrefToken::String("value".into(), p),
+ PrefToken::Paren(')', p),
+ PrefToken::Semicolon(p),
+ PrefToken::PrefFunction(p),
+ PrefToken::Paren('(', p),
+ PrefToken::String("example.pref.int".into(), p),
+ PrefToken::Comma(p),
+ PrefToken::Int(-123, p),
+ PrefToken::Paren(')', p),
+ PrefToken::Semicolon(p),
+ PrefToken::StickyPrefFunction(p),
+ PrefToken::Paren('(', p),
+ PrefToken::String("example.pref.bool".into(), p),
+ PrefToken::Comma(p),
+ PrefToken::Bool(false, p),
+ PrefToken::Paren(')', p),
+ PrefToken::Semicolon(p),
+ ];
+
+ tokenize_test(prefs, &expected);
+ }
+
+ #[test]
+ fn tokenize_comments() {
+ let prefs = "# bash style comment\n /*block comment*/ user_pref/*block comment*/(/*block \
+ comment*/ 'example.pref.string' /*block comment*/,/*block comment*/ \
+ 'value'/*block comment*/ )// line comment";
+
+ let p = Position::new();
+
+ let expected = vec![
+ PrefToken::CommentBashLine(" bash style comment".into(), p),
+ PrefToken::CommentBlock("block comment".into(), p),
+ PrefToken::UserPrefFunction(p),
+ PrefToken::CommentBlock("block comment".into(), p),
+ PrefToken::Paren('(', p),
+ PrefToken::CommentBlock("block comment".into(), p),
+ PrefToken::String("example.pref.string".into(), p),
+ PrefToken::CommentBlock("block comment".into(), p),
+ PrefToken::Comma(p),
+ PrefToken::CommentBlock("block comment".into(), p),
+ PrefToken::String("value".into(), p),
+ PrefToken::CommentBlock("block comment".into(), p),
+ PrefToken::Paren(')', p),
+ PrefToken::CommentLine(" line comment".into(), p),
+ ];
+
+ tokenize_test(prefs, &expected);
+ }
+
+ #[test]
+ fn tokenize_escapes() {
+ let prefs = r#"user_pref('example\x20pref', "\u0020\u2603\uD800\uDC96\"\'\n\r\\\w)"#;
+
+ let p = Position::new();
+
+ let expected = vec![
+ PrefToken::UserPrefFunction(p),
+ PrefToken::Paren('(', p),
+ PrefToken::String("example pref".into(), p),
+ PrefToken::Comma(p),
+ PrefToken::String(" ☃𐂖\"'\n\r\\\\w".into(), p),
+ PrefToken::Paren(')', p),
+ ];
+
+ tokenize_test(prefs, &expected);
+ }
+
+ fn tokenize_test(prefs: &str, expected: &[PrefToken]) {
+ println!("{}\n", prefs);
+
+ for (e, a) in expected.iter().zip(tokenize(prefs.as_bytes())) {
+ let success = match (e, &a) {
+ (&PrefToken::PrefFunction(_), &PrefToken::PrefFunction(_)) => true,
+ (&PrefToken::UserPrefFunction(_), &PrefToken::UserPrefFunction(_)) => true,
+ (&PrefToken::StickyPrefFunction(_), &PrefToken::StickyPrefFunction(_)) => true,
+ (
+ &PrefToken::CommentBlock(ref data_e, _),
+ &PrefToken::CommentBlock(ref data_a, _),
+ ) => data_e == data_a,
+ (
+ &PrefToken::CommentLine(ref data_e, _),
+ &PrefToken::CommentLine(ref data_a, _),
+ ) => data_e == data_a,
+ (
+ &PrefToken::CommentBashLine(ref data_e, _),
+ &PrefToken::CommentBashLine(ref data_a, _),
+ ) => data_e == data_a,
+ (&PrefToken::Paren(data_e, _), &PrefToken::Paren(data_a, _)) => data_e == data_a,
+ (&PrefToken::Semicolon(_), &PrefToken::Semicolon(_)) => true,
+ (&PrefToken::Comma(_), &PrefToken::Comma(_)) => true,
+ (&PrefToken::String(ref data_e, _), &PrefToken::String(ref data_a, _)) => {
+ data_e == data_a
+ }
+ (&PrefToken::Int(data_e, _), &PrefToken::Int(data_a, _)) => data_e == data_a,
+ (&PrefToken::Bool(data_e, _), &PrefToken::Bool(data_a, _)) => data_e == data_a,
+ (&PrefToken::Error(ref data_e, _), &PrefToken::Error(ref data_a, _)) => {
+ *data_e == *data_a
+ }
+ (_, _) => false,
+ };
+ if !success {
+ println!("Expected {:?}, got {:?}", e, a);
+ }
+ assert!(success);
+ }
+ }
+
+ #[test]
+ fn parse_simple() {
+ let input = " user_pref /* block comment */ ( 'example.pref.string', 'value' ) ;\n \
+ pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false)";
+
+ let mut expected: BTreeMap<String, Pref> = BTreeMap::new();
+ expected.insert("example.pref.string".into(), Pref::new("value"));
+ expected.insert("example.pref.int".into(), Pref::new(-123));
+ expected.insert("example.pref.bool".into(), Pref::new_sticky(false));
+
+ parse_test(input, expected);
+ }
+
+ #[test]
+ fn parse_escape() {
+ let input = r#"user_pref('example\\pref\"string', 'val\x20ue' )"#;
+
+ let mut expected: BTreeMap<String, Pref> = BTreeMap::new();
+ expected.insert("example\\pref\"string".into(), Pref::new("val ue"));
+
+ parse_test(input, expected);
+ }
+
+ #[test]
+ fn parse_empty() {
+ let inputs = ["", " ", "\n", "\n \n"];
+ for input in inputs {
+ let expected: BTreeMap<String, Pref> = BTreeMap::new();
+ parse_test(input, expected);
+ }
+ }
+
+ #[test]
+ fn parse_newline() {
+ let inputs = vec!["\na", "\n\nfoo"];
+ for input in inputs {
+ assert!(parse(input.as_bytes()).is_err());
+ }
+ }
+
+ #[test]
+ fn parse_minus() {
+ let inputs = ["pref(-", "user_pref(\"example.pref.int\", -);"];
+ for input in inputs {
+ assert!(parse(input.as_bytes()).is_err());
+ }
+ }
+
+ #[test]
+ fn parse_boolean_eof() {
+ let inputs = vec!["pref(true", "pref(false", "pref(false,", "pref(false)"];
+ for input in inputs {
+ assert!(parse(input.as_bytes()).is_err());
+ }
+ }
+
+ fn parse_test(input: &str, expected: BTreeMap<String, Pref>) {
+ match parse(input.as_bytes()) {
+ Ok(ref actual) => {
+ println!("Expected:\n{:?}\nActual\n{:?}", expected, actual);
+ assert_eq!(actual, &expected);
+ }
+ Err(e) => {
+ println!("{}", e);
+ assert!(false)
+ }
+ }
+ }
+
+ #[test]
+ fn serialize_simple() {
+ let input = " user_pref /* block comment */ ( 'example.pref.string', 'value' ) ;\n \
+ pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false)";
+ let expected = "sticky_pref(\"example.pref.bool\", false);
+user_pref(\"example.pref.int\", -123);
+user_pref(\"example.pref.string\", \"value\");\n";
+
+ serialize_test(input, expected);
+ }
+
+ #[test]
+ fn serialize_quotes() {
+ let input = r#"user_pref('example\\with"quotes"', '"Value"')"#;
+ let expected = r#"user_pref("example\\with\"quotes\"", "\"Value\"");
+"#;
+
+ serialize_test(input, expected);
+ }
+
+ fn serialize_test(input: &str, expected: &str) {
+ let buf = Vec::with_capacity(expected.len());
+ let mut out = Cursor::new(buf);
+ serialize(&parse(input.as_bytes()).unwrap(), &mut out).unwrap();
+ let data = out.into_inner();
+ let actual = str::from_utf8(&*data).unwrap();
+ println!("Expected:\n{:?}\nActual\n{:?}", expected, actual);
+ assert_eq!(actual, expected);
+ }
+}