Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/foam/lib/json/UnknownFObjectParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
package foam.lib.json;

import foam.lib.parse.*;
import foam.lang.X;

// TODO: Fix, doesn't parse {key:"}"}, use proper JSON parser
public class UnknownFObjectParser
implements Parser
{
Expand Down
58 changes: 58 additions & 0 deletions src/foam/lib/json/UnknownFObjectParserTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @license
* Copyright 2025 The FOAM Authors. All Rights Reserved.
* http://www.apache.org/licenses/LICENSE-2.0
*/

foam.CLASS({
package: 'foam.lib.json',
name: 'UnknownFObjectParserTest',
extends: 'foam.core.test.Test',

javaImports: [
'foam.lib.parse.*'
],

methods: [
{
name: 'runTest',
javaCode: `
// setup parser
var parser = UnknownFObjectParser.instance();
var psx = new ParserContextImpl();

// parse json
var input = "{\\"key\\":\\"value\\",\\"key2\\":true,\\"key3\\":null,\\"key4\\":{\\"foo\\":\\"bar\\"},\\"key5\\":[true,false,null,\\"text\\",1.23]}";
var ps = new StringPStream(input);
ps = (StringPStream) ps.apply(parser, psx);
test ( ps != null && ((UnknownFObject) ps.value()).getJson().equals(input), "Parsed json, input:" + input );

// parse empty json
var input2 = "{}";
ps = new StringPStream(input2);
ps = (StringPStream) ps.apply(parser, psx);
test ( ps != null && ((UnknownFObject) ps.value()).getJson().equals(input2), "Parsed empty json, input:" + input2 );

// parse json with un-quoted key
var input3 = "{key:\\"}\\"}";
ps = new StringPStream(input3);
ps = (StringPStream) ps.apply(parser, psx);
test ( ps != null && ((UnknownFObject) ps.value()).getJson().equals("{\\"key\\":\\"}\\"}"), "Parsed json with un-quoted key, input:" + input3 );

// parse json with comment line before key:value
var input4 = "{//comment1 \\n key:\\"1\\"," + "//comment2 \\n key2:\\"2\\"}";
var input4_print = "{//comment1 \\\\n key:\\"1\\"," + "//comment2 \\\\n key2:\\"2\\"}";
ps = new StringPStream(input4);
ps = (StringPStream) ps.apply(parser, psx);
test ( ps != null && ((UnknownFObject) ps.value()).getJson().equals("{\\"key\\":\\"1\\",\\"key2\\":\\"2\\"}"), "Parsed json with comment above properties, input:" + input4_print );

// parse empty json with just comments
var input5 = "{// comment1 \\n // comment2 \\n}";
var input5_print = "{// comment1 \\\\n // comment2 \\\\n}";
ps = new StringPStream(input5);
ps = (StringPStream) ps.apply(parser, psx);
test ( ps != null && ((UnknownFObject) ps.value()).getJson().equals("{}"), "Parsed empty json with just comment, input:" + input5_print );
`
}
]
});
2 changes: 1 addition & 1 deletion src/foam/lib/json/UnknownObjectParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public UnknownObjectParser() {

public PStream parse(PStream ps, ParserContext x) {
ps = ps.apply(delegate, x);
if ( ps == null) return null;
if ( ps == null ) return null;
return ps.setValue("{" + ps.value() + "}");
}
});
Expand Down
21 changes: 16 additions & 5 deletions src/foam/lib/json/UnknownPropertiesParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,34 @@
package foam.lib.json;

import foam.lib.parse.*;
import foam.util.SafetyUtil;

public class UnknownPropertiesParser
extends ProxyParser
{
public UnknownPropertiesParser() {
super(new Parser() {
Parser delegate = new Repeat(new Seq1(2, new Optional(CommentParser.create()), Whitespace.instance(), new Alt(new UnknownKeyValueParser0(), CommentParser.create())),
Literal.create(","));
Parser delegate = new Repeat(
new Seq1(1,
new Optional(CommentParser.create()),
new Alt(new UnknownKeyValueParser0(), Whitespace.instance())
), ",");

public PStream parse(PStream ps, ParserContext x) {
ps = ps.apply(delegate, x);
if ( ps == null ) return null;

Object[] objs = (Object[]) ps.value();
StringBuilder res = new StringBuilder();
for ( int i = 0 ; i < objs.length ; i++ ) {
res.append(objs[i].toString());
if ( i < objs.length - 1) {
res.append(',');
if ( objs[i] instanceof String str ) {
// Do not include empty string and invalid key-value pair
if ( SafetyUtil.isEmpty(str) || str.indexOf(":") == -1 ) continue;

res.append(str);
if ( i < objs.length - 1) {
res.append(',');
}
}
}
return ps.setValue(res.toString());
Expand Down
1 change: 1 addition & 0 deletions src/foam/lib/json/tests.jrl
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ p({"class":"foam.lib.json.ClassReferenceParserTest","id":"ClassReferenceParserTe
p({"class":"foam.lib.json.PropertyReferenceParserTest","id":"PropertyReferenceParserTest","description":"Tests the Property reference parser"})
p({"class":"foam.lib.json.StringToStringArrayParserTest","id":"StringToStringArrayParserTest","description":"Tests string data to string array parser"})
p({"class":"foam.lib.json.RawMapParserTest","id":"RawMapParserTest","description":"Tests raw map parser"})
p({"class":"foam.lib.json.UnknownFObjectParserTest","id":"UnknownFObjectParserTest","description":"Tests unknown fobject parser"})
1 change: 1 addition & 0 deletions src/pom.js
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,7 @@ foam.POM({
{ name: "foam/demos/u2/AllViews", flags: "web" },
{ name: "foam/lib/json/StringToStringArrayParserTest", flags: "js&test|java&test" },
{ name: "foam/lib/json/RawMapParserTest", flags: "js&test|java&test" },
{ name: "foam/lib/json/UnknownFObjectParserTest", flags: "js&test|java&test" },
{ name: "foam/audio/Speak", flags: "web" },
{ name: "foam/audio/Beep", flags: "web" }
],
Expand Down