diff --git a/coverage/clover.xml b/coverage/clover.xml
index 0adb42d..82e01a4 100644
--- a/coverage/clover.xml
+++ b/coverage/clover.xml
@@ -4,7 +4,7 @@
-
+
diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json
index 9c54684..a37dbd2 100644
--- a/coverage/coverage-final.json
+++ b/coverage/coverage-final.json
@@ -1,4 +1,4 @@
-{"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/ValueTypes.js": {"path":"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/ValueTypes.js","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":17,"column":1}},"1":{"start":{"line":3,"column":26},"end":{"line":3,"column":55}},"2":{"start":{"line":4,"column":28},"end":{"line":4,"column":59}},"3":{"start":{"line":5,"column":27},"end":{"line":5,"column":57}},"4":{"start":{"line":6,"column":29},"end":{"line":6,"column":61}},"5":{"start":{"line":7,"column":26},"end":{"line":7,"column":55}},"6":{"start":{"line":8,"column":28},"end":{"line":8,"column":59}},"7":{"start":{"line":9,"column":41},"end":{"line":9,"column":83}},"8":{"start":{"line":10,"column":34},"end":{"line":10,"column":70}},"9":{"start":{"line":11,"column":34},"end":{"line":11,"column":71}},"10":{"start":{"line":14,"column":8},"end":{"line":14,"column":24}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":13,"column":4},"end":{"line":13,"column":5}},"loc":{"start":{"line":13,"column":22},"end":{"line":15,"column":5}},"line":13}},"branchMap":{},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":27},"f":{"0":27},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"c4db0f40596059b5a1a7c22b8cbaafeac757f42a"}
+{"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/MetadataTypes.js": {"path":"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/MetadataTypes.js","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":17,"column":1}},"1":{"start":{"line":3,"column":26},"end":{"line":3,"column":55}},"2":{"start":{"line":4,"column":28},"end":{"line":4,"column":59}},"3":{"start":{"line":5,"column":27},"end":{"line":5,"column":57}},"4":{"start":{"line":6,"column":29},"end":{"line":6,"column":61}},"5":{"start":{"line":7,"column":26},"end":{"line":7,"column":55}},"6":{"start":{"line":8,"column":28},"end":{"line":8,"column":59}},"7":{"start":{"line":9,"column":41},"end":{"line":9,"column":83}},"8":{"start":{"line":10,"column":34},"end":{"line":10,"column":70}},"9":{"start":{"line":11,"column":34},"end":{"line":11,"column":71}},"10":{"start":{"line":14,"column":8},"end":{"line":14,"column":24}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":13,"column":4},"end":{"line":13,"column":5}},"loc":{"start":{"line":13,"column":22},"end":{"line":15,"column":5}},"line":13}},"branchMap":{},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":27},"f":{"0":27},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"c4db0f40596059b5a1a7c22b8cbaafeac757f42a"}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/parseTypes.js": {"path":"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/parseTypes.js","statementMap":{"0":{"start":{"line":1,"column":8},"end":{"line":1,"column":26}},"1":{"start":{"line":5,"column":16},"end":{"line":5,"column":18}},"2":{"start":{"line":9,"column":4},"end":{"line":86,"column":5}},"3":{"start":{"line":10,"column":8},"end":{"line":10,"column":47}},"4":{"start":{"line":13,"column":9},"end":{"line":86,"column":5}},"5":{"start":{"line":14,"column":8},"end":{"line":14,"column":51}},"6":{"start":{"line":17,"column":9},"end":{"line":86,"column":5}},"7":{"start":{"line":18,"column":8},"end":{"line":18,"column":46}},"8":{"start":{"line":21,"column":9},"end":{"line":86,"column":5}},"9":{"start":{"line":22,"column":8},"end":{"line":22,"column":50}},"10":{"start":{"line":25,"column":9},"end":{"line":86,"column":5}},"11":{"start":{"line":27,"column":30},"end":{"line":27,"column":32}},"12":{"start":{"line":29,"column":8},"end":{"line":81,"column":11}},"13":{"start":{"line":31,"column":12},"end":{"line":31,"column":83}},"14":{"start":{"line":31,"column":76},"end":{"line":31,"column":83}},"15":{"start":{"line":33,"column":29},"end":{"line":33,"column":31}},"16":{"start":{"line":34,"column":31},"end":{"line":34,"column":55}},"17":{"start":{"line":36,"column":12},"end":{"line":46,"column":13}},"18":{"start":{"line":37,"column":16},"end":{"line":37,"column":44}},"19":{"start":{"line":41,"column":16},"end":{"line":41,"column":45}},"20":{"start":{"line":43,"column":16},"end":{"line":45,"column":17}},"21":{"start":{"line":44,"column":20},"end":{"line":44,"column":71}},"22":{"start":{"line":48,"column":12},"end":{"line":50,"column":13}},"23":{"start":{"line":49,"column":16},"end":{"line":49,"column":45}},"24":{"start":{"line":52,"column":12},"end":{"line":52,"column":58}},"25":{"start":{"line":54,"column":12},"end":{"line":62,"column":13}},"26":{"start":{"line":56,"column":16},"end":{"line":61,"column":17}},"27":{"start":{"line":57,"column":20},"end":{"line":57,"column":59}},"28":{"start":{"line":60,"column":20},"end":{"line":60,"column":59}},"29":{"start":{"line":64,"column":12},"end":{"line":66,"column":13}},"30":{"start":{"line":65,"column":16},"end":{"line":65,"column":67}},"31":{"start":{"line":68,"column":12},"end":{"line":70,"column":13}},"32":{"start":{"line":69,"column":16},"end":{"line":69,"column":61}},"33":{"start":{"line":72,"column":12},"end":{"line":78,"column":13}},"34":{"start":{"line":73,"column":16},"end":{"line":73,"column":45}},"35":{"start":{"line":76,"column":17},"end":{"line":78,"column":13}},"36":{"start":{"line":77,"column":16},"end":{"line":77,"column":83}},"37":{"start":{"line":80,"column":12},"end":{"line":80,"column":49}},"38":{"start":{"line":85,"column":8},"end":{"line":85,"column":41}},"39":{"start":{"line":90,"column":8},"end":{"line":90,"column":38}},"40":{"start":{"line":93,"column":8},"end":{"line":102,"column":9}},"41":{"start":{"line":95,"column":12},"end":{"line":95,"column":44}},"42":{"start":{"line":96,"column":12},"end":{"line":96,"column":58}},"43":{"start":{"line":100,"column":12},"end":{"line":100,"column":68}},"44":{"start":{"line":101,"column":12},"end":{"line":101,"column":46}},"45":{"start":{"line":105,"column":4},"end":{"line":105,"column":17}},"46":{"start":{"line":109,"column":0},"end":{"line":109,"column":27}}},"fnMap":{"0":{"name":"parseType","decl":{"start":{"line":3,"column":9},"end":{"line":3,"column":18}},"loc":{"start":{"line":3,"column":40},"end":{"line":107,"column":1}},"line":3},"1":{"name":"(anonymous_1)","decl":{"start":{"line":29,"column":31},"end":{"line":29,"column":32}},"loc":{"start":{"line":29,"column":55},"end":{"line":81,"column":9}},"line":29},"2":{"name":"parseField","decl":{"start":{"line":88,"column":13},"end":{"line":88,"column":23}},"loc":{"start":{"line":88,"column":37},"end":{"line":103,"column":5}},"line":88}},"branchMap":{"0":{"loc":{"start":{"line":9,"column":4},"end":{"line":86,"column":5}},"type":"if","locations":[{"start":{"line":9,"column":4},"end":{"line":86,"column":5}},{"start":{"line":13,"column":9},"end":{"line":86,"column":5}}],"line":9},"1":{"loc":{"start":{"line":13,"column":9},"end":{"line":86,"column":5}},"type":"if","locations":[{"start":{"line":13,"column":9},"end":{"line":86,"column":5}},{"start":{"line":17,"column":9},"end":{"line":86,"column":5}}],"line":13},"2":{"loc":{"start":{"line":17,"column":9},"end":{"line":86,"column":5}},"type":"if","locations":[{"start":{"line":17,"column":9},"end":{"line":86,"column":5}},{"start":{"line":21,"column":9},"end":{"line":86,"column":5}}],"line":17},"3":{"loc":{"start":{"line":21,"column":9},"end":{"line":86,"column":5}},"type":"if","locations":[{"start":{"line":21,"column":9},"end":{"line":86,"column":5}},{"start":{"line":25,"column":9},"end":{"line":86,"column":5}}],"line":21},"4":{"loc":{"start":{"line":25,"column":9},"end":{"line":86,"column":5}},"type":"if","locations":[{"start":{"line":25,"column":9},"end":{"line":86,"column":5}},{"start":{"line":84,"column":8},"end":{"line":86,"column":5}}],"line":25},"5":{"loc":{"start":{"line":31,"column":12},"end":{"line":31,"column":83}},"type":"if","locations":[{"start":{"line":31,"column":12},"end":{"line":31,"column":83}},{"start":{},"end":{}}],"line":31},"6":{"loc":{"start":{"line":31,"column":15},"end":{"line":31,"column":74}},"type":"binary-expr","locations":[{"start":{"line":31,"column":15},"end":{"line":31,"column":39}},{"start":{"line":31,"column":43},"end":{"line":31,"column":74}}],"line":31},"7":{"loc":{"start":{"line":36,"column":12},"end":{"line":46,"column":13}},"type":"if","locations":[{"start":{"line":36,"column":12},"end":{"line":46,"column":13}},{"start":{"line":39,"column":16},"end":{"line":46,"column":13}}],"line":36},"8":{"loc":{"start":{"line":43,"column":16},"end":{"line":45,"column":17}},"type":"if","locations":[{"start":{"line":43,"column":16},"end":{"line":45,"column":17}},{"start":{},"end":{}}],"line":43},"9":{"loc":{"start":{"line":48,"column":12},"end":{"line":50,"column":13}},"type":"if","locations":[{"start":{"line":48,"column":12},"end":{"line":50,"column":13}},{"start":{},"end":{}}],"line":48},"10":{"loc":{"start":{"line":48,"column":15},"end":{"line":48,"column":62}},"type":"binary-expr","locations":[{"start":{"line":48,"column":15},"end":{"line":48,"column":37}},{"start":{"line":48,"column":41},"end":{"line":48,"column":62}}],"line":48},"11":{"loc":{"start":{"line":54,"column":12},"end":{"line":62,"column":13}},"type":"if","locations":[{"start":{"line":54,"column":12},"end":{"line":62,"column":13}},{"start":{},"end":{}}],"line":54},"12":{"loc":{"start":{"line":56,"column":16},"end":{"line":61,"column":17}},"type":"if","locations":[{"start":{"line":56,"column":16},"end":{"line":61,"column":17}},{"start":{"line":59,"column":20},"end":{"line":61,"column":17}}],"line":56},"13":{"loc":{"start":{"line":64,"column":12},"end":{"line":66,"column":13}},"type":"if","locations":[{"start":{"line":64,"column":12},"end":{"line":66,"column":13}},{"start":{},"end":{}}],"line":64},"14":{"loc":{"start":{"line":68,"column":12},"end":{"line":70,"column":13}},"type":"if","locations":[{"start":{"line":68,"column":12},"end":{"line":70,"column":13}},{"start":{},"end":{}}],"line":68},"15":{"loc":{"start":{"line":72,"column":12},"end":{"line":78,"column":13}},"type":"if","locations":[{"start":{"line":72,"column":12},"end":{"line":78,"column":13}},{"start":{"line":76,"column":17},"end":{"line":78,"column":13}}],"line":72},"16":{"loc":{"start":{"line":72,"column":15},"end":{"line":72,"column":66}},"type":"binary-expr","locations":[{"start":{"line":72,"column":15},"end":{"line":72,"column":41}},{"start":{"line":72,"column":45},"end":{"line":72,"column":66}}],"line":72},"17":{"loc":{"start":{"line":76,"column":17},"end":{"line":78,"column":13}},"type":"if","locations":[{"start":{"line":76,"column":17},"end":{"line":78,"column":13}},{"start":{},"end":{}}],"line":76},"18":{"loc":{"start":{"line":76,"column":20},"end":{"line":76,"column":71}},"type":"binary-expr","locations":[{"start":{"line":76,"column":20},"end":{"line":76,"column":46}},{"start":{"line":76,"column":50},"end":{"line":76,"column":71}}],"line":76},"19":{"loc":{"start":{"line":93,"column":8},"end":{"line":102,"column":9}},"type":"if","locations":[{"start":{"line":93,"column":8},"end":{"line":102,"column":9}},{"start":{"line":98,"column":12},"end":{"line":102,"column":9}}],"line":93}},"s":{"0":2,"1":35,"2":35,"3":4,"4":31,"5":5,"6":26,"7":2,"8":24,"9":3,"10":21,"11":17,"12":17,"13":70,"14":6,"15":64,"16":64,"17":64,"18":11,"19":53,"20":53,"21":2,"22":64,"23":8,"24":64,"25":64,"26":47,"27":36,"28":11,"29":64,"30":2,"31":64,"32":9,"33":64,"34":2,"35":62,"36":6,"37":64,"38":4,"39":68,"40":68,"41":64,"42":64,"43":4,"44":4,"45":35,"46":2},"f":{"0":35,"1":70,"2":68},"b":{"0":[4,31],"1":[5,26],"2":[2,24],"3":[3,21],"4":[17,4],"5":[6,64],"6":[70,66],"7":[11,53],"8":[2,51],"9":[8,56],"10":[64,8],"11":[47,17],"12":[36,11],"13":[2,62],"14":[9,55],"15":[2,62],"16":[64,8],"17":[6,56],"18":[62,6],"19":[64,4]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"8536198c35a2e60c5a433c578c28b25a6c58ee94"}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/utils.js": {"path":"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/utils.js","statementMap":{"0":{"start":{"line":1,"column":16},"end":{"line":1,"column":44}},"1":{"start":{"line":2,"column":17},"end":{"line":2,"column":47}},"2":{"start":{"line":5,"column":9},"end":{"line":5,"column":37}},"3":{"start":{"line":5,"column":18},"end":{"line":5,"column":37}},"4":{"start":{"line":6,"column":8},"end":{"line":6,"column":10}},"5":{"start":{"line":9,"column":12},"end":{"line":9,"column":37}},"6":{"start":{"line":9,"column":21},"end":{"line":9,"column":37}},"7":{"start":{"line":10,"column":16},"end":{"line":10,"column":40}},"8":{"start":{"line":10,"column":25},"end":{"line":10,"column":40}},"9":{"start":{"line":11,"column":15},"end":{"line":11,"column":39}},"10":{"start":{"line":11,"column":24},"end":{"line":11,"column":39}},"11":{"start":{"line":15,"column":21},"end":{"line":15,"column":43}},"12":{"start":{"line":15,"column":30},"end":{"line":15,"column":43}},"13":{"start":{"line":16,"column":19},"end":{"line":16,"column":41}},"14":{"start":{"line":16,"column":28},"end":{"line":16,"column":41}},"15":{"start":{"line":18,"column":23},"end":{"line":18,"column":55}},"16":{"start":{"line":18,"column":32},"end":{"line":18,"column":55}},"17":{"start":{"line":20,"column":16},"end":{"line":20,"column":77}},"18":{"start":{"line":20,"column":26},"end":{"line":20,"column":76}},"19":{"start":{"line":22,"column":15},"end":{"line":22,"column":37}},"20":{"start":{"line":22,"column":24},"end":{"line":22,"column":37}},"21":{"start":{"line":24,"column":28},"end":{"line":24,"column":73}},"22":{"start":{"line":24,"column":40},"end":{"line":24,"column":73}},"23":{"start":{"line":26,"column":29},"end":{"line":26,"column":63}},"24":{"start":{"line":26,"column":38},"end":{"line":26,"column":63}},"25":{"start":{"line":28,"column":26},"end":{"line":28,"column":54}},"26":{"start":{"line":28,"column":35},"end":{"line":28,"column":54}},"27":{"start":{"line":30,"column":15},"end":{"line":30,"column":48}},"28":{"start":{"line":30,"column":24},"end":{"line":30,"column":48}},"29":{"start":{"line":32,"column":18},"end":{"line":32,"column":105}},"30":{"start":{"line":32,"column":27},"end":{"line":32,"column":105}},"31":{"start":{"line":34,"column":27},"end":{"line":34,"column":61}},"32":{"start":{"line":34,"column":36},"end":{"line":34,"column":61}},"33":{"start":{"line":36,"column":23},"end":{"line":36,"column":58}},"34":{"start":{"line":36,"column":32},"end":{"line":36,"column":58}},"35":{"start":{"line":38,"column":20},"end":{"line":38,"column":59}},"36":{"start":{"line":38,"column":29},"end":{"line":38,"column":59}},"37":{"start":{"line":40,"column":22},"end":{"line":40,"column":61}},"38":{"start":{"line":40,"column":31},"end":{"line":40,"column":61}},"39":{"start":{"line":42,"column":19},"end":{"line":42,"column":63}},"40":{"start":{"line":42,"column":28},"end":{"line":42,"column":63}},"41":{"start":{"line":44,"column":22},"end":{"line":44,"column":108}},"42":{"start":{"line":44,"column":31},"end":{"line":44,"column":108}},"43":{"start":{"line":46,"column":20},"end":{"line":46,"column":61}},"44":{"start":{"line":46,"column":29},"end":{"line":46,"column":61}},"45":{"start":{"line":48,"column":15},"end":{"line":48,"column":44}},"46":{"start":{"line":48,"column":24},"end":{"line":48,"column":44}},"47":{"start":{"line":50,"column":29},"end":{"line":50,"column":84}},"48":{"start":{"line":50,"column":39},"end":{"line":50,"column":83}},"49":{"start":{"line":52,"column":24},"end":{"line":52,"column":112}},"50":{"start":{"line":52,"column":33},"end":{"line":52,"column":112}},"51":{"start":{"line":54,"column":20},"end":{"line":54,"column":40}},"52":{"start":{"line":54,"column":29},"end":{"line":54,"column":40}},"53":{"start":{"line":56,"column":17},"end":{"line":60,"column":1}},"54":{"start":{"line":58,"column":4},"end":{"line":58,"column":37}},"55":{"start":{"line":58,"column":24},"end":{"line":58,"column":37}},"56":{"start":{"line":59,"column":4},"end":{"line":59,"column":43}},"57":{"start":{"line":62,"column":17},"end":{"line":67,"column":1}},"58":{"start":{"line":64,"column":4},"end":{"line":64,"column":38}},"59":{"start":{"line":64,"column":25},"end":{"line":64,"column":38}},"60":{"start":{"line":66,"column":4},"end":{"line":66,"column":47}},"61":{"start":{"line":69,"column":20},"end":{"line":69,"column":58}},"62":{"start":{"line":69,"column":29},"end":{"line":69,"column":58}},"63":{"start":{"line":71,"column":20},"end":{"line":71,"column":58}},"64":{"start":{"line":71,"column":38},"end":{"line":71,"column":58}},"65":{"start":{"line":73,"column":26},"end":{"line":89,"column":1}},"66":{"start":{"line":76,"column":50},"end":{"line":76,"column":62}},"67":{"start":{"line":78,"column":4},"end":{"line":88,"column":5}},"68":{"start":{"line":91,"column":23},"end":{"line":97,"column":1}},"69":{"start":{"line":93,"column":4},"end":{"line":96,"column":5}},"70":{"start":{"line":99,"column":25},"end":{"line":110,"column":1}},"71":{"start":{"line":101,"column":32},"end":{"line":101,"column":44}},"72":{"start":{"line":103,"column":4},"end":{"line":109,"column":5}},"73":{"start":{"line":112,"column":22},"end":{"line":122,"column":1}},"74":{"start":{"line":115,"column":42},"end":{"line":115,"column":54}},"75":{"start":{"line":117,"column":4},"end":{"line":120,"column":5}},"76":{"start":{"line":124,"column":17},"end":{"line":135,"column":1}},"77":{"start":{"line":126,"column":4},"end":{"line":128,"column":5}},"78":{"start":{"line":127,"column":8},"end":{"line":127,"column":45}},"79":{"start":{"line":130,"column":4},"end":{"line":133,"column":5}},"80":{"start":{"line":137,"column":18},"end":{"line":156,"column":1}},"81":{"start":{"line":139,"column":15},"end":{"line":139,"column":40}},"82":{"start":{"line":141,"column":4},"end":{"line":149,"column":5}},"83":{"start":{"line":142,"column":8},"end":{"line":142,"column":38}},"84":{"start":{"line":144,"column":9},"end":{"line":149,"column":5}},"85":{"start":{"line":145,"column":8},"end":{"line":145,"column":46}},"86":{"start":{"line":147,"column":9},"end":{"line":149,"column":5}},"87":{"start":{"line":148,"column":8},"end":{"line":148,"column":46}},"88":{"start":{"line":151,"column":4},"end":{"line":154,"column":5}},"89":{"start":{"line":158,"column":19},"end":{"line":158,"column":79}},"90":{"start":{"line":158,"column":29},"end":{"line":158,"column":79}},"91":{"start":{"line":160,"column":30},"end":{"line":160,"column":65}},"92":{"start":{"line":160,"column":39},"end":{"line":160,"column":65}},"93":{"start":{"line":162,"column":18},"end":{"line":170,"column":1}},"94":{"start":{"line":164,"column":35},"end":{"line":164,"column":47}},"95":{"start":{"line":166,"column":18},"end":{"line":166,"column":70}},"96":{"start":{"line":168,"column":4},"end":{"line":168,"column":68}},"97":{"start":{"line":172,"column":16},"end":{"line":188,"column":1}},"98":{"start":{"line":190,"column":16},"end":{"line":276,"column":1}},"99":{"start":{"line":278,"column":0},"end":{"line":284,"column":71}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":9},"end":{"line":5,"column":10}},"loc":{"start":{"line":5,"column":18},"end":{"line":5,"column":37}},"line":5},"1":{"name":"(anonymous_1)","decl":{"start":{"line":9,"column":12},"end":{"line":9,"column":13}},"loc":{"start":{"line":9,"column":21},"end":{"line":9,"column":37}},"line":9},"2":{"name":"(anonymous_2)","decl":{"start":{"line":10,"column":16},"end":{"line":10,"column":17}},"loc":{"start":{"line":10,"column":25},"end":{"line":10,"column":40}},"line":10},"3":{"name":"(anonymous_3)","decl":{"start":{"line":11,"column":15},"end":{"line":11,"column":16}},"loc":{"start":{"line":11,"column":24},"end":{"line":11,"column":39}},"line":11},"4":{"name":"(anonymous_4)","decl":{"start":{"line":15,"column":21},"end":{"line":15,"column":22}},"loc":{"start":{"line":15,"column":30},"end":{"line":15,"column":43}},"line":15},"5":{"name":"(anonymous_5)","decl":{"start":{"line":16,"column":19},"end":{"line":16,"column":20}},"loc":{"start":{"line":16,"column":28},"end":{"line":16,"column":41}},"line":16},"6":{"name":"(anonymous_6)","decl":{"start":{"line":18,"column":23},"end":{"line":18,"column":24}},"loc":{"start":{"line":18,"column":32},"end":{"line":18,"column":55}},"line":18},"7":{"name":"(anonymous_7)","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":17}},"loc":{"start":{"line":20,"column":26},"end":{"line":20,"column":76}},"line":20},"8":{"name":"(anonymous_8)","decl":{"start":{"line":22,"column":15},"end":{"line":22,"column":16}},"loc":{"start":{"line":22,"column":24},"end":{"line":22,"column":37}},"line":22},"9":{"name":"(anonymous_9)","decl":{"start":{"line":24,"column":28},"end":{"line":24,"column":29}},"loc":{"start":{"line":24,"column":40},"end":{"line":24,"column":73}},"line":24},"10":{"name":"(anonymous_10)","decl":{"start":{"line":26,"column":29},"end":{"line":26,"column":30}},"loc":{"start":{"line":26,"column":38},"end":{"line":26,"column":63}},"line":26},"11":{"name":"(anonymous_11)","decl":{"start":{"line":28,"column":26},"end":{"line":28,"column":27}},"loc":{"start":{"line":28,"column":35},"end":{"line":28,"column":54}},"line":28},"12":{"name":"(anonymous_12)","decl":{"start":{"line":30,"column":15},"end":{"line":30,"column":16}},"loc":{"start":{"line":30,"column":24},"end":{"line":30,"column":48}},"line":30},"13":{"name":"(anonymous_13)","decl":{"start":{"line":32,"column":18},"end":{"line":32,"column":19}},"loc":{"start":{"line":32,"column":27},"end":{"line":32,"column":105}},"line":32},"14":{"name":"(anonymous_14)","decl":{"start":{"line":34,"column":27},"end":{"line":34,"column":28}},"loc":{"start":{"line":34,"column":36},"end":{"line":34,"column":61}},"line":34},"15":{"name":"(anonymous_15)","decl":{"start":{"line":36,"column":23},"end":{"line":36,"column":24}},"loc":{"start":{"line":36,"column":32},"end":{"line":36,"column":58}},"line":36},"16":{"name":"(anonymous_16)","decl":{"start":{"line":38,"column":20},"end":{"line":38,"column":21}},"loc":{"start":{"line":38,"column":29},"end":{"line":38,"column":59}},"line":38},"17":{"name":"(anonymous_17)","decl":{"start":{"line":40,"column":22},"end":{"line":40,"column":23}},"loc":{"start":{"line":40,"column":31},"end":{"line":40,"column":61}},"line":40},"18":{"name":"(anonymous_18)","decl":{"start":{"line":42,"column":19},"end":{"line":42,"column":20}},"loc":{"start":{"line":42,"column":28},"end":{"line":42,"column":63}},"line":42},"19":{"name":"(anonymous_19)","decl":{"start":{"line":44,"column":22},"end":{"line":44,"column":23}},"loc":{"start":{"line":44,"column":31},"end":{"line":44,"column":108}},"line":44},"20":{"name":"(anonymous_20)","decl":{"start":{"line":46,"column":20},"end":{"line":46,"column":21}},"loc":{"start":{"line":46,"column":29},"end":{"line":46,"column":61}},"line":46},"21":{"name":"(anonymous_21)","decl":{"start":{"line":48,"column":15},"end":{"line":48,"column":16}},"loc":{"start":{"line":48,"column":24},"end":{"line":48,"column":44}},"line":48},"22":{"name":"(anonymous_22)","decl":{"start":{"line":50,"column":29},"end":{"line":50,"column":30}},"loc":{"start":{"line":50,"column":39},"end":{"line":50,"column":83}},"line":50},"23":{"name":"(anonymous_23)","decl":{"start":{"line":52,"column":24},"end":{"line":52,"column":25}},"loc":{"start":{"line":52,"column":33},"end":{"line":52,"column":112}},"line":52},"24":{"name":"(anonymous_24)","decl":{"start":{"line":54,"column":20},"end":{"line":54,"column":21}},"loc":{"start":{"line":54,"column":29},"end":{"line":54,"column":40}},"line":54},"25":{"name":"(anonymous_25)","decl":{"start":{"line":56,"column":17},"end":{"line":56,"column":18}},"loc":{"start":{"line":56,"column":25},"end":{"line":60,"column":1}},"line":56},"26":{"name":"(anonymous_26)","decl":{"start":{"line":62,"column":17},"end":{"line":62,"column":18}},"loc":{"start":{"line":62,"column":26},"end":{"line":67,"column":1}},"line":62},"27":{"name":"(anonymous_27)","decl":{"start":{"line":69,"column":20},"end":{"line":69,"column":21}},"loc":{"start":{"line":69,"column":29},"end":{"line":69,"column":58}},"line":69},"28":{"name":"(anonymous_28)","decl":{"start":{"line":71,"column":20},"end":{"line":71,"column":21}},"loc":{"start":{"line":71,"column":38},"end":{"line":71,"column":58}},"line":71},"29":{"name":"(anonymous_29)","decl":{"start":{"line":73,"column":26},"end":{"line":73,"column":27}},"loc":{"start":{"line":73,"column":35},"end":{"line":89,"column":1}},"line":73},"30":{"name":"(anonymous_30)","decl":{"start":{"line":91,"column":23},"end":{"line":91,"column":24}},"loc":{"start":{"line":91,"column":32},"end":{"line":97,"column":1}},"line":91},"31":{"name":"(anonymous_31)","decl":{"start":{"line":99,"column":25},"end":{"line":99,"column":26}},"loc":{"start":{"line":99,"column":34},"end":{"line":110,"column":1}},"line":99},"32":{"name":"(anonymous_32)","decl":{"start":{"line":112,"column":22},"end":{"line":112,"column":23}},"loc":{"start":{"line":112,"column":31},"end":{"line":122,"column":1}},"line":112},"33":{"name":"(anonymous_33)","decl":{"start":{"line":124,"column":17},"end":{"line":124,"column":18}},"loc":{"start":{"line":124,"column":35},"end":{"line":135,"column":1}},"line":124},"34":{"name":"(anonymous_34)","decl":{"start":{"line":137,"column":18},"end":{"line":137,"column":19}},"loc":{"start":{"line":137,"column":30},"end":{"line":156,"column":1}},"line":137},"35":{"name":"(anonymous_35)","decl":{"start":{"line":158,"column":19},"end":{"line":158,"column":20}},"loc":{"start":{"line":158,"column":29},"end":{"line":158,"column":79}},"line":158},"36":{"name":"(anonymous_36)","decl":{"start":{"line":160,"column":30},"end":{"line":160,"column":31}},"loc":{"start":{"line":160,"column":39},"end":{"line":160,"column":65}},"line":160},"37":{"name":"(anonymous_37)","decl":{"start":{"line":162,"column":18},"end":{"line":162,"column":19}},"loc":{"start":{"line":162,"column":44},"end":{"line":170,"column":1}},"line":162}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":26},"end":{"line":20,"column":76}},"type":"binary-expr","locations":[{"start":{"line":20,"column":26},"end":{"line":20,"column":39}},{"start":{"line":20,"column":43},"end":{"line":20,"column":61}},{"start":{"line":20,"column":65},"end":{"line":20,"column":76}}],"line":20},"1":{"loc":{"start":{"line":50,"column":39},"end":{"line":50,"column":83}},"type":"binary-expr","locations":[{"start":{"line":50,"column":39},"end":{"line":50,"column":60}},{"start":{"line":50,"column":64},"end":{"line":50,"column":83}}],"line":50},"2":{"loc":{"start":{"line":52,"column":33},"end":{"line":52,"column":112}},"type":"binary-expr","locations":[{"start":{"line":52,"column":33},"end":{"line":52,"column":73}},{"start":{"line":52,"column":77},"end":{"line":52,"column":112}}],"line":52},"3":{"loc":{"start":{"line":58,"column":4},"end":{"line":58,"column":37}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":37}},{"start":{},"end":{}}],"line":58},"4":{"loc":{"start":{"line":64,"column":4},"end":{"line":64,"column":38}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":64,"column":38}},{"start":{},"end":{}}],"line":64},"5":{"loc":{"start":{"line":126,"column":4},"end":{"line":128,"column":5}},"type":"if","locations":[{"start":{"line":126,"column":4},"end":{"line":128,"column":5}},{"start":{},"end":{}}],"line":126},"6":{"loc":{"start":{"line":131,"column":15},"end":{"line":131,"column":82}},"type":"cond-expr","locations":[{"start":{"line":131,"column":33},"end":{"line":131,"column":55}},{"start":{"line":131,"column":58},"end":{"line":131,"column":82}}],"line":131},"7":{"loc":{"start":{"line":141,"column":4},"end":{"line":149,"column":5}},"type":"if","locations":[{"start":{"line":141,"column":4},"end":{"line":149,"column":5}},{"start":{"line":144,"column":9},"end":{"line":149,"column":5}}],"line":141},"8":{"loc":{"start":{"line":144,"column":9},"end":{"line":149,"column":5}},"type":"if","locations":[{"start":{"line":144,"column":9},"end":{"line":149,"column":5}},{"start":{"line":147,"column":9},"end":{"line":149,"column":5}}],"line":144},"9":{"loc":{"start":{"line":147,"column":9},"end":{"line":149,"column":5}},"type":"if","locations":[{"start":{"line":147,"column":9},"end":{"line":149,"column":5}},{"start":{},"end":{}}],"line":147},"10":{"loc":{"start":{"line":158,"column":29},"end":{"line":158,"column":79}},"type":"cond-expr","locations":[{"start":{"line":158,"column":53},"end":{"line":158,"column":71}},{"start":{"line":158,"column":74},"end":{"line":158,"column":79}}],"line":158},"11":{"loc":{"start":{"line":168,"column":25},"end":{"line":168,"column":61}},"type":"cond-expr","locations":[{"start":{"line":168,"column":35},"end":{"line":168,"column":42}},{"start":{"line":168,"column":45},"end":{"line":168,"column":61}}],"line":168}},"s":{"0":3,"1":3,"2":3,"3":977,"4":3,"5":3,"6":456,"7":3,"8":204,"9":3,"10":150,"11":3,"12":2,"13":3,"14":2,"15":3,"16":7,"17":3,"18":1157,"19":3,"20":18,"21":3,"22":108,"23":3,"24":116,"25":3,"26":23,"27":3,"28":162,"29":3,"30":72,"31":3,"32":13,"33":3,"34":100,"35":3,"36":28,"37":3,"38":26,"39":3,"40":37,"41":3,"42":73,"43":3,"44":128,"45":3,"46":66,"47":3,"48":119,"49":3,"50":64,"51":3,"52":37,"53":3,"54":1095,"55":0,"56":1095,"57":3,"58":62,"59":3,"60":59,"61":3,"62":13,"63":3,"64":99,"65":3,"66":6,"67":6,"68":3,"69":3,"70":3,"71":4,"72":4,"73":3,"74":5,"75":5,"76":3,"77":85,"78":17,"79":85,"80":3,"81":75,"82":75,"83":8,"84":67,"85":1,"86":66,"87":10,"88":75,"89":3,"90":70,"91":3,"92":2,"93":3,"94":2,"95":2,"96":2,"97":3,"98":3,"99":3},"f":{"0":977,"1":456,"2":204,"3":150,"4":2,"5":2,"6":7,"7":1157,"8":18,"9":108,"10":116,"11":23,"12":162,"13":72,"14":13,"15":100,"16":28,"17":26,"18":37,"19":73,"20":128,"21":66,"22":119,"23":64,"24":37,"25":1095,"26":62,"27":13,"28":99,"29":6,"30":3,"31":4,"32":5,"33":85,"34":75,"35":70,"36":2,"37":2},"b":{"0":[1157,1155,1155],"1":[119,4],"2":[64,4],"3":[0,1095],"4":[3,59],"5":[17,68],"6":[25,60],"7":[8,67],"8":[1,66],"9":[10,56],"10":[5,65],"11":[1,1]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"73c9bb981a006549413ea9ab8e165f57e2771b55"}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/mappings/cpq.js": {"path":"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/mappings/cpq.js","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":165,"column":1}}},"fnMap":{},"branchMap":{},"s":{"0":3},"f":{},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"f9adbe3250802f3a70e96d42479456badd9b7fe3"}
diff --git a/coverage/coverage-summary.json b/coverage/coverage-summary.json
index ebdb095..c020e67 100644
--- a/coverage/coverage-summary.json
+++ b/coverage/coverage-summary.json
@@ -1,10 +1,10 @@
-{"total": {"lines":{"total":212,"covered":210,"skipped":0,"pct":99.05},"statements":{"total":244,"covered":240,"skipped":0,"pct":98.36},"functions":{"total":49,"covered":49,"skipped":0,"pct":100},"branches":{"total":103,"covered":99,"skipped":0,"pct":96.11},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/ValueTypes.js": {"lines":{"total":11,"covered":11,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":11,"covered":11,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+{"total": {"lines":{"total":213,"covered":211,"skipped":0,"pct":99.06},"statements":{"total":245,"covered":242,"skipped":0,"pct":98.77},"functions":{"total":49,"covered":49,"skipped":0,"pct":100},"branches":{"total":103,"covered":100,"skipped":0,"pct":97.08},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/MetadataTypes.js": {"lines":{"total":11,"covered":11,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":11,"covered":11,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/parseTypes.js": {"lines":{"total":48,"covered":48,"skipped":0,"pct":100},"functions":{"total":3,"covered":3,"skipped":0,"pct":100},"statements":{"total":49,"covered":49,"skipped":0,"pct":100},"branches":{"total":40,"covered":40,"skipped":0,"pct":100}}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/utils.js": {"lines":{"total":6,"covered":6,"skipped":0,"pct":100},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":11,"covered":11,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/mappings/cpq.js": {"lines":{"total":1,"covered":1,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":1,"covered":1,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/parser/grammar.js": {"lines":{"total":21,"covered":21,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":21,"covered":21,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/parser/grammarChecks.js": {"lines":{"total":29,"covered":29,"skipped":0,"pct":100},"functions":{"total":20,"covered":20,"skipped":0,"pct":100},"statements":{"total":47,"covered":45,"skipped":0,"pct":95.74},"branches":{"total":11,"covered":9,"skipped":0,"pct":81.81}}
+,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/parser/grammarChecks.js": {"lines":{"total":30,"covered":30,"skipped":0,"pct":100},"functions":{"total":20,"covered":20,"skipped":0,"pct":100},"statements":{"total":48,"covered":47,"skipped":0,"pct":97.91},"branches":{"total":11,"covered":10,"skipped":0,"pct":90.9}}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/lib/parser/transformations.js": {"lines":{"total":40,"covered":40,"skipped":0,"pct":100},"functions":{"total":13,"covered":13,"skipped":0,"pct":100},"statements":{"total":46,"covered":46,"skipped":0,"pct":100},"branches":{"total":14,"covered":14,"skipped":0,"pct":100}}
,"/Users/pgonzalez/Documents/apps/sfdc-formula-parser/src/index.js": {"lines":{"total":56,"covered":54,"skipped":0,"pct":96.42},"functions":{"total":7,"covered":7,"skipped":0,"pct":100},"statements":{"total":58,"covered":56,"skipped":0,"pct":96.55},"branches":{"total":38,"covered":36,"skipped":0,"pct":94.73}}
}
diff --git a/coverage/lcov.info b/coverage/lcov.info
index a591f76..17e6590 100644
--- a/coverage/lcov.info
+++ b/coverage/lcov.info
@@ -1,5 +1,5 @@
TN:
-SF:lib/ValueTypes.js
+SF:lib/MetadataTypes.js
FN:13,(anonymous_0)
FNF:1
FNH:1
@@ -132,17 +132,17 @@ FN:5,(anonymous_3)
FN:6,(anonymous_4)
FNF:5
FNH:5
-FNDA:936,(anonymous_0)
-FNDA:438,(anonymous_1)
-FNDA:196,(anonymous_2)
-FNDA:143,(anonymous_3)
+FNDA:974,(anonymous_0)
+FNDA:455,(anonymous_1)
+FNDA:201,(anonymous_2)
+FNDA:151,(anonymous_3)
FNDA:7,(anonymous_4)
-DA:2,936
-DA:3,438
-DA:4,196
-DA:5,143
+DA:2,974
+DA:3,455
+DA:4,201
+DA:5,151
DA:6,7
-DA:9,3
+DA:9,5
LF:6
LH:6
BRF:0
@@ -152,7 +152,7 @@ TN:
SF:lib/mappings/cpq.js
FNF:0
FNH:0
-DA:1,2
+DA:1,3
LF:1
LH:1
BRF:0
@@ -162,27 +162,27 @@ TN:
SF:lib/parser/grammar.js
FNF:0
FNH:0
-DA:1,2
-DA:3,2
-DA:5,2
-DA:7,2
-DA:9,2
-DA:11,2
-DA:13,2
-DA:15,2
-DA:17,2
-DA:19,2
-DA:21,2
-DA:23,2
-DA:25,2
-DA:27,2
-DA:29,2
-DA:31,2
-DA:33,2
-DA:35,2
-DA:37,2
-DA:55,2
-DA:143,2
+DA:1,4
+DA:3,4
+DA:5,4
+DA:7,4
+DA:9,4
+DA:11,4
+DA:13,4
+DA:15,4
+DA:17,4
+DA:19,4
+DA:21,4
+DA:23,4
+DA:25,4
+DA:27,4
+DA:29,4
+DA:31,4
+DA:33,4
+DA:35,4
+DA:37,4
+DA:55,4
+DA:143,4
LF:21
LH:21
BRF:0
@@ -208,74 +208,75 @@ FN:31,(anonymous_14)
FN:33,(anonymous_15)
FN:35,(anonymous_16)
FN:39,(anonymous_17)
-FN:43,(anonymous_18)
-FN:49,(anonymous_19)
+FN:46,(anonymous_18)
+FN:52,(anonymous_19)
FNF:20
FNH:20
FNDA:2,(anonymous_0)
FNDA:2,(anonymous_1)
-FNDA:1148,(anonymous_2)
+FNDA:1157,(anonymous_2)
FNDA:18,(anonymous_3)
-FNDA:105,(anonymous_4)
-FNDA:112,(anonymous_5)
-FNDA:21,(anonymous_6)
-FNDA:152,(anonymous_7)
-FNDA:64,(anonymous_8)
-FNDA:97,(anonymous_9)
-FNDA:26,(anonymous_10)
-FNDA:24,(anonymous_11)
-FNDA:35,(anonymous_12)
-FNDA:70,(anonymous_13)
-FNDA:126,(anonymous_14)
-FNDA:64,(anonymous_15)
+FNDA:108,(anonymous_4)
+FNDA:116,(anonymous_5)
+FNDA:23,(anonymous_6)
+FNDA:162,(anonymous_7)
+FNDA:72,(anonymous_8)
+FNDA:100,(anonymous_9)
+FNDA:28,(anonymous_10)
+FNDA:26,(anonymous_11)
+FNDA:37,(anonymous_12)
+FNDA:73,(anonymous_13)
+FNDA:128,(anonymous_14)
+FNDA:66,(anonymous_15)
FNDA:119,(anonymous_16)
FNDA:64,(anonymous_17)
-FNDA:1092,(anonymous_18)
-FNDA:56,(anonymous_19)
-DA:1,2
-DA:2,2
-DA:4,2
-DA:5,2
-DA:7,1148
+FNDA:1095,(anonymous_18)
+FNDA:62,(anonymous_19)
+DA:1,4
+DA:2,4
+DA:4,4
+DA:5,4
+DA:7,1157
DA:9,18
-DA:11,105
-DA:13,112
-DA:15,21
-DA:17,152
-DA:19,64
-DA:21,97
-DA:23,26
-DA:25,24
-DA:27,35
-DA:29,70
-DA:31,126
-DA:33,64
-DA:35,2
+DA:11,108
+DA:13,116
+DA:15,23
+DA:17,162
+DA:19,72
+DA:21,100
+DA:23,28
+DA:25,26
+DA:27,37
+DA:29,73
+DA:31,128
+DA:33,66
+DA:35,4
DA:36,119
-DA:39,2
-DA:40,64
-DA:43,2
-DA:45,1092
-DA:46,1092
-DA:49,2
-DA:51,56
-DA:53,56
-DA:56,2
-LF:29
-LH:29
-BRDA:7,0,0,1148
-BRDA:7,0,1,1148
-BRDA:7,0,2,1148
+DA:39,4
+DA:41,64
+DA:43,64
+DA:46,4
+DA:48,1095
+DA:49,1095
+DA:52,4
+DA:54,62
+DA:56,59
+DA:59,4
+LF:30
+LH:30
+BRDA:7,0,0,1157
+BRDA:7,0,1,1155
+BRDA:7,0,2,1155
BRDA:36,1,0,119
BRDA:36,1,1,4
-BRDA:40,2,0,64
-BRDA:40,2,1,4
-BRDA:45,3,0,0
-BRDA:45,3,1,1092
-BRDA:51,4,0,0
-BRDA:51,4,1,56
+BRDA:43,2,0,64
+BRDA:43,2,1,4
+BRDA:48,3,0,0
+BRDA:48,3,1,1095
+BRDA:54,4,0,3
+BRDA:54,4,1,59
BRF:11
-BRH:9
+BRH:10
end_of_record
TN:
SF:lib/parser/transformations.js
@@ -294,73 +295,73 @@ FN:102,(anonymous_11)
FN:104,(anonymous_12)
FNF:13
FNH:13
-FNDA:36,(anonymous_0)
-FNDA:9,(anonymous_1)
-FNDA:11,(anonymous_2)
-FNDA:93,(anonymous_3)
-FNDA:5,(anonymous_4)
-FNDA:2,(anonymous_5)
-FNDA:3,(anonymous_6)
-FNDA:4,(anonymous_7)
-FNDA:80,(anonymous_8)
-FNDA:72,(anonymous_9)
-FNDA:68,(anonymous_10)
+FNDA:37,(anonymous_0)
+FNDA:13,(anonymous_1)
+FNDA:13,(anonymous_2)
+FNDA:99,(anonymous_3)
+FNDA:6,(anonymous_4)
+FNDA:3,(anonymous_5)
+FNDA:4,(anonymous_6)
+FNDA:5,(anonymous_7)
+FNDA:85,(anonymous_8)
+FNDA:75,(anonymous_9)
+FNDA:70,(anonymous_10)
FNDA:2,(anonymous_11)
FNDA:2,(anonymous_12)
-DA:1,2
-DA:2,2
-DA:3,2
-DA:4,2
-DA:5,2
-DA:7,36
-DA:9,9
-DA:11,11
-DA:13,93
-DA:15,2
-DA:18,5
-DA:20,5
-DA:33,2
-DA:35,2
-DA:41,2
-DA:43,3
-DA:45,3
-DA:54,2
-DA:57,4
-DA:59,4
-DA:66,2
-DA:68,80
-DA:69,12
-DA:72,80
-DA:79,2
-DA:81,72
-DA:83,72
-DA:84,6
-DA:86,66
+DA:1,3
+DA:2,3
+DA:3,3
+DA:4,3
+DA:5,3
+DA:7,37
+DA:9,13
+DA:11,13
+DA:13,99
+DA:15,3
+DA:18,6
+DA:20,6
+DA:33,3
+DA:35,3
+DA:41,3
+DA:43,4
+DA:45,4
+DA:54,3
+DA:57,5
+DA:59,5
+DA:66,3
+DA:68,85
+DA:69,17
+DA:72,85
+DA:79,3
+DA:81,75
+DA:83,75
+DA:84,8
+DA:86,67
DA:87,1
-DA:89,65
+DA:89,66
DA:90,10
-DA:93,72
-DA:100,68
-DA:102,2
-DA:104,2
+DA:93,75
+DA:100,70
+DA:102,3
+DA:104,3
DA:106,2
DA:108,2
DA:110,2
-DA:114,2
+DA:114,3
LF:40
LH:40
-BRDA:68,0,0,12
+BRDA:68,0,0,17
BRDA:68,0,1,68
-BRDA:73,1,0,21
-BRDA:73,1,1,59
-BRDA:83,2,0,6
-BRDA:83,2,1,66
+BRDA:73,1,0,25
+BRDA:73,1,1,60
+BRDA:83,2,0,8
+BRDA:83,2,1,67
BRDA:86,3,0,1
-BRDA:86,3,1,65
+BRDA:86,3,1,66
BRDA:89,4,0,10
-BRDA:89,4,1,55
-BRDA:100,5,0,4
-BRDA:100,5,1,64
+BRDA:89,4,1,56
+BRDA:100,5,0,5
+BRDA:100,5,1,65
BRDA:110,6,0,1
BRDA:110,6,1,1
BRF:14
diff --git a/lib/MetadataTypes.js b/lib/MetadataTypes.js
new file mode 100644
index 0000000..78ea138
--- /dev/null
+++ b/lib/MetadataTypes.js
@@ -0,0 +1,17 @@
+module.exports = class MetadataType {
+
+ static CUSTOM_FIELD = new MetadataType("customFields")
+ static STANDARD_FIELD = new MetadataType("standardFields")
+ static CUSTOM_OBJECT = new MetadataType("customObjects")
+ static STANDARD_OBJECT = new MetadataType("standardObjects")
+ static CUSTOM_LABEL = new MetadataType("customLabels")
+ static CUSTOM_SETTING = new MetadataType("customSettings")
+ static CUSTOM_METADATA_TYPE_RECORD = new MetadataType("customMetadataTypeRecords")
+ static CUSTOM_METADATA_TYPE = new MetadataType("customMetadataTypes")
+ static UNKNOWN_RELATIONSHIP = new MetadataType("unknownRelationships")
+
+ constructor(name) {
+ this.name = name
+ }
+
+}
\ No newline at end of file
diff --git a/lib/ValueTypes.js b/lib/ValueTypes.js
deleted file mode 100644
index 27e204d..0000000
--- a/lib/ValueTypes.js
+++ /dev/null
@@ -1,17 +0,0 @@
-module.exports = class ValueType {
-
- static CUSTOM_FIELD = new ValueType("customFields")
- static STANDARD_FIELD = new ValueType("standardFields")
- static CUSTOM_OBJECT = new ValueType("customObjects")
- static STANDARD_OBJECT = new ValueType("standardObjects")
- static CUSTOM_LABEL = new ValueType("customLabels")
- static CUSTOM_SETTING = new ValueType("customSettings")
- static CUSTOM_METADATA_TYPE_RECORD = new ValueType("customMetadataTypeRecords")
- static CUSTOM_METADATA_TYPE = new ValueType("customMetadataTypes")
- static UNKNOWN_RELATIONSHIP = new ValueType("unknownRelationships")
-
- constructor(name) {
- this.name = name
- }
-
-}
\ No newline at end of file
diff --git a/lib/parser/grammarChecks.js b/lib/parser/grammarChecks.js
index 7cbb2fa..62aba4e 100644
--- a/lib/parser/grammarChecks.js
+++ b/lib/parser/grammarChecks.js
@@ -1,5 +1,5 @@
const G = require('../parser/grammar');
-const _ = require('../utils');
+const {$,getField,getObject,parts} = require('../utils');
let isCommentStart = value => value == G.COMMENT_START;
let isCommentEnd = value => value == G.COMMENT_END;
@@ -10,34 +10,37 @@ let isNumber = value => !isNaN(value);
let isInterestingOperator = operator => ![',','(',')'].includes(operator);
-let isStandardRelationship = value => !_.$(value).endsWith(G.RELATIONSHIP_SUFFIX);
+let isStandardRelationship = value => !$(value).endsWith(G.RELATIONSHIP_SUFFIX);
let isRelationshipField = value => value.includes('.');
-let isCustom = value => _.$(value).endsWith(G.CUSTOM_ENTITY_SUFFIX);
+let isCustom = value => $(value).endsWith(G.CUSTOM_ENTITY_SUFFIX);
-let isUserField = value => G.USER_FIELDS.includes(_.$(_.getObject(value)));
+let isUserField = value => G.USER_FIELDS.includes($(getObject(value)));
-let isCustomMetadata = value => _.$(value).includes(G.CUSTOM_METADATA_PREFIX);
+let isCustomMetadata = value => $(value).includes(G.CUSTOM_METADATA_PREFIX);
-let isCustomLabel = value => _.$(value).startsWith(G.CUSTOM_LABEL_PREFIX);
+let isCustomLabel = value => $(value).startsWith(G.CUSTOM_LABEL_PREFIX);
-let isCustomSetting = value => _.$(value).startsWith(G.CUSTOM_SETTING_PREFIX);
+let isCustomSetting = value => $(value).startsWith(G.CUSTOM_SETTING_PREFIX);
-let isObjectType = value => _.$(value).startsWith(G.OBJECT_TYPE_PREFIX);
+let isObjectType = value => $(value).startsWith(G.OBJECT_TYPE_PREFIX);
-let isSpecialPrefix = value => G.SPECIAL_PREFIXES.includes(_.$(value));
+let isSpecialPrefix = value => G.SPECIAL_PREFIXES.includes($(value));
-let isParentField = value => _.$(_.getField(value)) == G.SELF_REFERENTIAL_PARENT_FIELD;
+let isParentField = value => $(getField(value)) == G.SELF_REFERENTIAL_PARENT_FIELD;
-let isParent = value => _.$(value) == G.SELF_REFERENTIAL_PARENT_OBJECT;
+let isParent = value => $(value) == G.SELF_REFERENTIAL_PARENT_OBJECT;
let isProcessBuilderPrefix = value => {
return value.startsWith(G.PROCESS_BUILDER_BRACKET_START) && value.endsWith(G.PROCESS_BUILDER_BRACKET_END);
}
let isCPQRelationship = value => {
- return _.$(_.getObject(value)).startsWith(G.CPQ_NAMESPACE) && _.$(_.getObject(value)).endsWith(G.RELATIONSHIP_SUFFIX);
+
+ let obj = $(getObject(value));
+
+ return obj.startsWith(G.CPQ_NAMESPACE) && obj.endsWith(G.RELATIONSHIP_SUFFIX);
}
let isOperator = char => {
@@ -50,7 +53,7 @@ let isFunction = value => {
if(isNothing(value)) return false;
- return G.FUNCTIONS.includes(_.$(value.trim()));
+ return G.FUNCTIONS.includes($(value.trim()));
};
module.exports = {isFunction,isOperator,
diff --git a/lib/parser/transformations.js b/lib/parser/transformations.js
index 129ab54..df6c0f8 100644
--- a/lib/parser/transformations.js
+++ b/lib/parser/transformations.js
@@ -1,12 +1,12 @@
-const G = require('../parser/grammar');
+const {STANDARD_RELATIONSHIP_ID_NAME,DOLLAR_SIGN} = require('../parser/grammar');
const cpqMapping = require('../mappings/cpq')
-const _ = require('../utils');
-const ValueType = require('../ValueTypes');
+const {$,getField,parts} = require('../utils');
+const MetadataType = require('../MetadataTypes');
const {isCustom,isCustomMetadata,isStandardRelationship} = require('../parser/grammarChecks');
-let transformToId = value => value+=G.STANDARD_RELATIONSHIP_ID_NAME;
+let transformToId = value => value+=STANDARD_RELATIONSHIP_ID_NAME;
-let transformToUserField = value => `User.${_.getField(value)}`;
+let transformToUserField = value => `User.${getField(value)}`;
let replaceRwithC = value => value.slice(0,-1).concat('c');
@@ -15,16 +15,16 @@ let createApiName = (object,field) => `${object}.${field}`;
let parseCustomMetadata = value => {
//$CustomMetadata.Trigger_Context_Status__mdt.SRM_Metadata_c.Enable_After_Insert__c
- let [mdType,sobject,sobjInstance,fieldName] = _.parts(value);
+ let [mdType,sobject,sobjInstance,fieldName] = parts(value);
return [
{
instance: createApiName(sobject,sobjInstance),
- type: ValueType.CUSTOM_METADATA_TYPE_RECORD
+ type: MetadataType.CUSTOM_METADATA_TYPE_RECORD
},
{
instance : sobject,
- type: ValueType.CUSTOM_METADATA_TYPE
+ type: MetadataType.CUSTOM_METADATA_TYPE
},
parseField(fieldName,sobject)
]
@@ -33,18 +33,18 @@ let parseCustomMetadata = value => {
let parseCustomLabel = value => {
return {
- type:ValueType.CUSTOM_LABEL,
- instance: _.getField(value)
+ type:MetadataType.CUSTOM_LABEL,
+ instance: getField(value)
}
}
let parseCustomSetting = value => {
- let [prefix,object,field] = _.parts(value);
+ let [prefix,object,field] = parts(value);
return [
{
- type:ValueType.CUSTOM_SETTING,
+ type:MetadataType.CUSTOM_SETTING,
instance:object
},
parseField(field,object)
@@ -54,7 +54,7 @@ let parseCustomSetting = value => {
let parseObjectType = value => {
//$ObjectType.Center__c.Fields.My_text_field__c
- let [mdType,sobject,prop,fieldName] = _.parts(value);
+ let [mdType,sobject,prop,fieldName] = parts(value);
return [
parseField(fieldName,sobject),
@@ -70,7 +70,7 @@ let parseField = (value,object) => {
}
return {
- type: (isCustom(value) ? ValueType.CUSTOM_FIELD : ValueType.STANDARD_FIELD ),
+ type: (isCustom(value) ? MetadataType.CUSTOM_FIELD : MetadataType.STANDARD_FIELD ),
instance: value
}
@@ -78,16 +78,16 @@ let parseField = (value,object) => {
let parseObject = (object) => {
- let type = ValueType.STANDARD_OBJECT;
+ let type = MetadataType.STANDARD_OBJECT;
if(isCustom(object)){
- type = ValueType.CUSTOM_OBJECT
+ type = MetadataType.CUSTOM_OBJECT
}
else if(isCustomMetadata(object)){
- type = ValueType.CUSTOM_METADATA_TYPE;
+ type = MetadataType.CUSTOM_METADATA_TYPE;
}
else if(!isStandardRelationship(object)){
- type = ValueType.UNKNOWN_RELATIONSHIP;
+ type = MetadataType.UNKNOWN_RELATIONSHIP;
}
return {
@@ -97,15 +97,15 @@ let parseObject = (object) => {
}
-let removePrefix = value => value.startsWith(G.DOLLAR_SIGN) ? value.substring(1) : value
+let removePrefix = value => value.startsWith(DOLLAR_SIGN) ? value.substring(1) : value
let removeFirstAndLastChars = value => value.slice(1).slice(0,-1)
let mapCPQField = (value,originalObject) => {
- let [relationshipName,field] = _.parts(value);
+ let [relationshipName,field] = parts(value);
- let apiName = cpqMapping[_.$(originalObject)]?.[_.$(relationshipName)];
+ let apiName = cpqMapping[$(originalObject)]?.[$(relationshipName)];
return createApiName(apiName ? apiName : relationshipName,field)
diff --git a/package.json b/package.json
index 37d9ef8..ba9de0f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "forcemula",
- "version": "0.0.1",
+ "version": "0.1.0",
"description": "Extract fields from Salesforce formulas",
"main": "src/index.js",
"scripts": {
diff --git a/src/index.js b/src/index.js
index def0fe6..fb0cb57 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,7 @@
let parseType = require('../lib/parseTypes');
let _ = require('../lib/utils');
let check = require('../lib/parser/grammarChecks')
-let ValueType = require('../lib/ValueTypes');
+let MetadataType = require('../lib/MetadataTypes');
function parse({object,formula}){
diff --git a/tests/e2e.test.js b/tests/e2e.test.js
index fc2d680..491085d 100644
--- a/tests/e2e.test.js
+++ b/tests/e2e.test.js
@@ -68,10 +68,6 @@ test('Standard formula: e2e test', () => {
let result = parse({object:'OpportunityLineItem',formula});
- console.log(result)
-
-
-
let expectedFunctions = [
'IF','TRUE','FALSE','TEXT'
]
diff --git a/tests/grammarChecks.test.js b/tests/grammarChecks.test.js
index e69de29..e6863cf 100644
--- a/tests/grammarChecks.test.js
+++ b/tests/grammarChecks.test.js
@@ -0,0 +1,136 @@
+let _ = require('../lib/parser/grammarChecks');
+
+test('The * should be considered an operator',() =>{
+ expect(_.isOperator('*')).toBe(true);
+ })
+
+ test('The word ISBLANK should not be an operator',() =>{
+ expect(_.isOperator('ISBLANK')).toBe(false);
+ })
+
+ test('Operators should be identified even if there is white space around them',() =>{
+ expect(_.isOperator('* ')).toBe(true);
+ })
+
+ test('The word ISBLANK should be considered a function',() =>{
+ expect(_.isFunction('ISBLANK')).toBe(true);
+ })
+
+ test('The case (upper or lower) of a function should not affect its determination',() =>{
+ expect(_.isFunction('IsBLank')).toBe(true);
+ })
+
+ test('Functions should be identified even if theres white space around them',() =>{
+ expect(_.isFunction('IsBLank ')).toBe(true);
+ })
+
+ test('The "isFunction" function should return false on falsy values',() =>{
+ expect(_.isFunction(undefined)).toBe(false);
+ expect(_.isFunction('')).toBe(false);
+ expect(_.isFunction(null)).toBe(false);
+ })
+
+
+ test('Whether a field is custom or standard is determined by whether the field ends with __c, irrespective of the case',() =>{
+ expect(_.isCustom('Account__C')).toBe(true);
+ expect(_.isCustom('AccountId')).toBe(false);
+ })
+
+
+ test('Only certain operators should be considered "interesting" ',() =>{
+
+ expect(_.isInterestingOperator('*')).toBe(true);
+ expect(_.isInterestingOperator(',')).toBe(false);
+ expect(_.isInterestingOperator('(')).toBe(false);
+
+ })
+
+ test('If a field does not end with __r, it should be considered a standard relationship',() =>{
+
+ expect(_.isStandardRelationship('Account')).toBe(true);
+ expect(_.isStandardRelationship('Account__r')).toBe(false);
+ expect(_.isStandardRelationship('Lead__R')).toBe(false);
+
+ })
+
+ test('Certain fields (such as Owner, CreatedBy, etc.) should be considered User fields', () => {
+
+ expect(_.isUserField('Owner.FirstName')).toBe(true);
+ expect(_.isUserField('Manager.FirstName')).toBe(true);
+ expect(_.isUserField('CreatedBy.FirstName')).toBe(true);
+ expect(_.isUserField('LastModifiedBY.FirstName')).toBe(true);
+ //upper case
+ expect(_.isUserField('OWNER.FirstName')).toBe(true);
+ expect(_.isUserField('MANAger.FirstName')).toBe(true);
+ expect(_.isUserField('CREATEDBy.FirstName')).toBe(true);
+ expect(_.isUserField('lastmodifiEDBY.FirstName')).toBe(true);
+
+ })
+
+
+ test('Custom Metadata is determined by the presence of the word __MDT anywhere in the field name', () => {
+ expect(_.isCustomMetadata(`$CustomMetadata.Trigger_Context_Status__mdt.SRM_Metadata_c.Enable_After_Insert__c`)).toBe(true);
+ //upper case
+ expect(_.isCustomMetadata(`$CustomMetadata.Trigger_Context_Status__mDT.SRM_Metadata_c.Enable_After_Insert__c`)).toBe(true);
+ })
+
+
+
+ test('Custom Labels are determined by the $Label prefix', () => {
+ expect(_.isCustomLabel(`$Label.SomeName`)).toBe(true);
+ //upper case
+ expect(_.isCustomLabel(`$LaBEL.SomeName`)).toBe(true);
+ })
+
+
+
+
+ test('Custom Settings are determined by the $Setup prefix', () => {
+ expect(_.isCustomSetting(`$Setup.SomeName`)).toBe(true);
+ //upper case
+ expect(_.isCustomSetting(`$SeTUP.SomeName`)).toBe(true);
+ })
+
+
+
+ test('Object Types are determined by the $ObjectType prefix', () => {
+ expect(_.isObjectType(`$ObjectType.Center__c.Fields.My_text_field__c`)).toBe(true);
+ //upper case
+ expect(_.isObjectType(`$ObjectTYPE.Center__c.Fields.My_text_field__c`)).toBe(true);
+ })
+
+
+
+ test('A field is considered a relationship field if there is a dot in between' ,() => {
+
+ expect(_.isRelationshipField('Account.Name')).toBe(true);
+ expect(_.isRelationshipField('Name')).toBe(false);
+
+ })
+
+
+
+ test('Certain prefixes should be considered of a special type' ,() => {
+
+ expect(_.isSpecialPrefix('$Organization')).toBe(true);
+ expect(_.isSpecialPrefix('$PROfile')).toBe(true);
+ expect(_.isSpecialPrefix('$ObjectType')).toBe(false);
+
+ })
+
+ test('If a field ends in ParentId, it should be considered a parent field' ,() => {
+
+ expect(_.isParentField('Account.Parent')).toBe(false);
+ expect(_.isParentField('Account.parEnTid')).toBe(true);
+
+ })
+
+ test('The word "parent" in a custom field should determine that this is a parent relationship' ,() => {
+
+ expect(_.isParent('ParentId')).toBe(false);
+ expect(_.isParent('Parent')).toBe(true);
+
+ })
+
+
+
\ No newline at end of file
diff --git a/tests/parseFields.test.js b/tests/parseFields.test.js
index 5a1eec8..f8dae6a 100644
--- a/tests/parseFields.test.js
+++ b/tests/parseFields.test.js
@@ -1,5 +1,5 @@
let parseType = require('../lib/parseTypes');
-const ValueType = require('../lib/ValueTypes');
+const MetadataType = require('../lib/MetadataTypes');
let originalObject = 'Account';
@@ -9,11 +9,11 @@ test('Passing a single STANDARD field name should return the same field, but wit
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Account.Name'
},
{
- type : ValueType.STANDARD_OBJECT,
+ type : MetadataType.STANDARD_OBJECT,
instance:'Account'
}
]
@@ -27,11 +27,11 @@ test('Passing a single CUSTOM field name should return the same field, but with
let expected = [
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'lead__c.custom__C'
},
{
- type : ValueType.CUSTOM_OBJECT,
+ type : MetadataType.CUSTOM_OBJECT,
instance:'lead__c'
}
]
@@ -50,32 +50,32 @@ test('Standard self-referential relationships should be converted back to their
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'OpportunityLineItem.OpportunityId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Opportunity.AccountId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Account.ParentId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Account.AccountNumber'
},
{
- type : ValueType.STANDARD_OBJECT,
+ type : MetadataType.STANDARD_OBJECT,
instance:'OpportunityLineItem'
}
,
{
- type : ValueType.STANDARD_OBJECT,
+ type : MetadataType.STANDARD_OBJECT,
instance:'Opportunity'
},
{
- type : ValueType.STANDARD_OBJECT,
+ type : MetadataType.STANDARD_OBJECT,
instance:'Account'
}
]
@@ -91,15 +91,15 @@ test('STANDARD relationships should be converted to their original field name',(
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Contact.AccountId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Account.OpportunityId'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'Opportunity.Custom__c'
}
]
@@ -115,15 +115,15 @@ test('CUSTOM relationships should be converted to their original field name',()
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Contact.AccountId'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'Account.Opportunity__c'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Opportunity__r.Name'
}
]
@@ -139,23 +139,23 @@ test('A mix of custom and standard relationships should result in the same conve
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Lead.AccountId'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'Account.Opportunity__c'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Opportunity__r.AssetId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Asset.ContactId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Contact.FirstName'
}
]
@@ -172,28 +172,28 @@ test('A chain of custom relationships should be supported',() =>{
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Order.AccountId'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'Account.first__c'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'first__r.second__c'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'second__r.third__c'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'third__r.fourth__c'
}
,
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'third__r.fourth__c'
}
]
@@ -211,28 +211,28 @@ test('User-related fields should be transformed to User.[field]', () => {
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Order.AccountId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Account.OwnerId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'User.ContactId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Contact.AccountId'
},
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Account.LastModifiedById'
}
,
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'User.Department'
}
]
@@ -249,11 +249,11 @@ test('Custom metadata fields should be parsed to both types and fields (custom f
let expected = [
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'Trigger_Context_Status__mdt.Enable_After_Insert__c'
},
{
- type : ValueType.CUSTOM_METADATA_TYPE_RECORD,
+ type : MetadataType.CUSTOM_METADATA_TYPE_RECORD,
instance:'Trigger_Context_Status__mdt.SRM_Metadata_c'
}
]
@@ -268,11 +268,11 @@ test('Custom metadata fields should be parsed to both types and fields (standard
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Trigger_Context_Status__mdt.QualifiedApiName'
},
{
- type : ValueType.CUSTOM_METADATA_TYPE_RECORD,
+ type : MetadataType.CUSTOM_METADATA_TYPE_RECORD,
instance:'Trigger_Context_Status__mdt.SRM_Metadata_c'
}
]
@@ -289,11 +289,11 @@ test('Custom Settings should be parsed as both a type and a field instance', ()
let expected = [
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'Customer_Support_Setting__c.Email_Address__c'
},
{
- type : ValueType.CUSTOM_SETTING,
+ type : MetadataType.CUSTOM_SETTING,
instance:'Customer_Support_Setting__c'
}
]
@@ -306,11 +306,11 @@ test('Custom Settings should be parsed as both a type and a field instance', ()
expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Customer_Support_Setting__c.DeveloperName'
},
{
- type : ValueType.CUSTOM_SETTING,
+ type : MetadataType.CUSTOM_SETTING,
instance:'Customer_Support_Setting__c'
}
]
@@ -325,7 +325,7 @@ test('Custom Labels should be parsed to their API name', () => {
let expected = [
{
- type : ValueType.CUSTOM_LABEL,
+ type : MetadataType.CUSTOM_LABEL,
instance:'AWS_Access_Key'
}
]
@@ -334,7 +334,7 @@ test('Custom Labels should be parsed to their API name', () => {
let notExpected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Case.LabelId'
}
]
@@ -349,7 +349,7 @@ test('Object Types should be parsed to their API name (standard fields)', () =>
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Center__c.CreatedDate'
}
]
@@ -358,7 +358,7 @@ test('Object Types should be parsed to their API name (standard fields)', () =>
let notExpected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Case.ObjectTypeId'
}
]
@@ -373,7 +373,7 @@ test('Object Types should be parsed to their API name (custom fields)', () => {
let expected = [
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'Center__c.Custom__c'
}
]
@@ -382,7 +382,7 @@ test('Object Types should be parsed to their API name (custom fields)', () => {
let notExpected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Case.ObjectTypeId'
}
]
@@ -399,11 +399,11 @@ test(`The $ prefix should be removed from special objects and
let expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'User.ManagerId'
},
{
- type : ValueType.CUSTOM_FIELD,
+ type : MetadataType.CUSTOM_FIELD,
instance:'User.Employee_Id__c'
}
]
@@ -412,7 +412,7 @@ test(`The $ prefix should be removed from special objects and
let notExpected = [
{
- type:ValueType.STANDARD_FIELD,
+ type:MetadataType.STANDARD_FIELD,
instance:'Case.UserId'
}
]
@@ -425,7 +425,7 @@ test(`The $ prefix should be removed from special objects and
expected = [
{
- type : ValueType.STANDARD_FIELD,
+ type : MetadataType.STANDARD_FIELD,
instance:'Organization.TimeZone'
}
]
@@ -434,7 +434,7 @@ test(`The $ prefix should be removed from special objects and
notExpected = [
{
- type:ValueType.STANDARD_FIELD,
+ type:MetadataType.STANDARD_FIELD,
instance:'Case.OrganizationId'
}
]
diff --git a/tests/transformations.test.js b/tests/transformations.test.js
new file mode 100644
index 0000000..0562e2e
--- /dev/null
+++ b/tests/transformations.test.js
@@ -0,0 +1,144 @@
+let _ = require('../lib/parser/transformations');
+let MetadataType = require('../lib/MetadataTypes');
+
+
+test('Custom fields should be returned with their original object as a prefix, and the correct MetadataType',() =>{
+
+ let value = _.parseField(`My_text_field__c`,'Account');
+
+ expect(value).toHaveProperty('instance','Account.My_text_field__c')
+ expect(value).toHaveProperty('type',MetadataType.CUSTOM_FIELD);
+
+
+})
+
+test('Standard fields should be returned with their original object as a prefix, and the correct MetadataType',() =>{
+
+ let value = _.parseField(`Industry`,'Account');
+
+ expect(value).toHaveProperty('instance','Account.Industry')
+ expect(value).toHaveProperty('type',MetadataType.STANDARD_FIELD);
+})
+
+
+test('User fields should be transformed to their original API name', () => {
+
+ expect(_.transformToUserField('Owner.FirstName')).toBe('User.FirstName');
+ expect(_.transformToUserField('Manager.FirstName')).toBe('User.FirstName');
+ expect(_.transformToUserField('CreatedBy.FirstName')).toBe('User.FirstName');
+ expect(_.transformToUserField('LastModifiedBY.area__c')).toBe('User.area__c');
+
+})
+
+test('The "transformToId" function should add "Id" at the end of the field name', () => {
+ expect(_.transformToId('Owner.Manager')).toBe('Owner.ManagerId');
+})
+
+test('The "replaceRwithC" function should replace __r with __c', () => {
+ expect(_.replaceRwithC('Owner.custom__r')).toBe('Owner.custom__c');
+ //upper case
+ expect(_.replaceRwithC('Owner.custom__R')).toBe('Owner.custom__c');
+})
+
+test('Custom Metadata should be converted to both custom fields and metadata types', () => {
+
+ let field = '$CustomMetadata.Trigger_Context_Status__mdt.SRM_Metadata_c.Enable_After_Insert__c';
+ let value = _.parseCustomMetadata(field)
+
+ expect(value.length).toBe(3);
+
+ value.forEach(val => {
+
+ if(val.type == MetadataType.CUSTOM_FIELD){
+ expect(val.instance).toBe('Trigger_Context_Status__mdt.Enable_After_Insert__c')
+ }
+
+ if(val.type == MetadataType.CUSTOM_METADATA_TYPE_RECORD){
+ expect(val.instance).toBe('Trigger_Context_Status__mdt.SRM_Metadata_c')
+ }
+
+ if(val.type == MetadataType.CUSTOM_METADATA_TYPE){
+ expect(val.instance).toBe('Trigger_Context_Status__mdt')
+ }
+
+ })
+})
+
+test('Custom Labels should be parsed by removing the $Label prefix and adding the correct MetadataType', () => {
+
+ let value = _.parseCustomLabel(`$Label.SomeName`);
+
+ expect(value).toHaveProperty('instance','SomeName')
+ expect(value).toHaveProperty('type',MetadataType.CUSTOM_LABEL);
+})
+
+test('Custom Settings should be parsed by removing the $Setting prefix and adding the correct MetadataType', () => {
+
+ let types = _.parseCustomSetting(`$Setup.My_Setting__c.my_field__c`);
+
+ let expected = [
+ {
+ type : MetadataType.CUSTOM_FIELD,
+ instance:'My_Setting__c.my_field__c'
+ },
+ {
+ type : MetadataType.CUSTOM_SETTING,
+ instance:'My_Setting__c'
+ }
+ ]
+
+ expect(types).toEqual(expect.arrayContaining(expected));
+
+})
+
+
+test('Object Types are parsed by removing the unnecessary prefixes and returning the field API name', () => {
+
+ let types = _.parseObjectType(`$ObjectType.Center__c.Fields.My_text_field__c`);
+
+ let expected = [
+ {
+ instance:'Center__c.My_text_field__c',
+ type:MetadataType.CUSTOM_FIELD
+ },
+ {
+ instance:'Center__c',
+ type:MetadataType.CUSTOM_OBJECT
+ }
+ ]
+
+ expect(types).toEqual(expect.arrayContaining(expected));
+
+
+})
+
+test('The "removePrefix" function should remove the $ character' ,() => {
+
+ expect(_.removePrefix('$Organization.Name')).toBe('Organization.Name');
+ expect(_.removePrefix('User.RoleId')).toBe('User.RoleId');
+
+})
+
+
+test('Parse object should determine if the object is standard or custom' ,() => {
+
+ let result = _.parseObject('Account');
+
+ let expected = {
+ instance:'Account',
+ type:MetadataType.STANDARD_OBJECT
+ }
+
+ expect(result).toEqual(expected);
+
+ result = _.parseObject('Account__c');
+
+ expected = {
+ instance:'Account__c',
+ type:MetadataType.CUSTOM_OBJECT
+ }
+
+ expect(result).toEqual(expected);
+
+})
+
diff --git a/tests/utils.test.js b/tests/utils.test.js
index 5585e05..36571d8 100644
--- a/tests/utils.test.js
+++ b/tests/utils.test.js
@@ -1,268 +1,24 @@
let _ = require('../lib/utils');
-let ValueType = require('../lib/ValueTypes');
-
-
-test('The * should be considered an operator',() =>{
- expect(_.isOperator('*')).toBe(true);
-})
-
-test('The word ISBLANK should not be an operator',() =>{
- expect(_.isOperator('ISBLANK')).toBe(false);
-})
-
-test('Operators should be identified even if there is white space around them',() =>{
- expect(_.isOperator('* ')).toBe(true);
-})
-
-test('The word ISBLANK should be considered a function',() =>{
- expect(_.isFunction('ISBLANK')).toBe(true);
-})
-
-test('The case (upper or lower) of a function should not affect its determination',() =>{
- expect(_.isFunction('IsBLank')).toBe(true);
-})
-
-test('Functions should be identified even if theres white space around them',() =>{
- expect(_.isFunction('IsBLank ')).toBe(true);
-})
-
-test('The "isFunction" function should return false on falsy values',() =>{
- expect(_.isFunction(undefined)).toBe(false);
- expect(_.isFunction('')).toBe(false);
- expect(_.isFunction(null)).toBe(false);
-})
+let fieldName = 'Opportunity.StageName';
+let fieldNameParts = ['Opportunity','StageName'];
test('White space should be removed',() =>{
expect(_.removeWhiteSpace(' there is space ')).toBe('thereisspace');
})
-test('Whether a field is custom or standard is determined by whether the field ends with __c, irrespective of the case',() =>{
- expect(_.isCustom('Account__C')).toBe(true);
- expect(_.isCustom('AccountId')).toBe(false);
-})
-
-test('Custom fields should be returned with their original object as a prefix, and the correct ValueType',() =>{
-
- let value = _.parseField(`My_text_field__c`,'Account');
-
- expect(value).toHaveProperty('instance','Account.My_text_field__c')
- expect(value).toHaveProperty('type',ValueType.CUSTOM_FIELD);
-
-
-})
-
-test('Standard fields should be returned with their original object as a prefix, and the correct ValueType',() =>{
-
- let value = _.parseField(`Industry`,'Account');
-
- expect(value).toHaveProperty('instance','Account.Industry')
- expect(value).toHaveProperty('type',ValueType.STANDARD_FIELD);
-})
-
-
-
-test('Only certain operators should be considered "interesting" ',() =>{
-
- expect(_.isInterestingOperator('*')).toBe(true);
- expect(_.isInterestingOperator(',')).toBe(false);
- expect(_.isInterestingOperator('(')).toBe(false);
-
-})
-
-test('If a field does not end with __r, it should be considered a standard relationship',() =>{
-
- expect(_.isStandardRelationship('Account')).toBe(true);
- expect(_.isStandardRelationship('Account__r')).toBe(false);
- expect(_.isStandardRelationship('Lead__R')).toBe(false);
-
-})
-
-test('Certain fields (such as Owner, CreatedBy, etc.) should be considered User fields', () => {
-
- expect(_.isUserField('Owner.FirstName')).toBe(true);
- expect(_.isUserField('Manager.FirstName')).toBe(true);
- expect(_.isUserField('CreatedBy.FirstName')).toBe(true);
- expect(_.isUserField('LastModifiedBY.FirstName')).toBe(true);
- //upper case
- expect(_.isUserField('OWNER.FirstName')).toBe(true);
- expect(_.isUserField('MANAger.FirstName')).toBe(true);
- expect(_.isUserField('CREATEDBy.FirstName')).toBe(true);
- expect(_.isUserField('lastmodifiEDBY.FirstName')).toBe(true);
-
-})
-
-test('User fields should be transformed to their original API name', () => {
-
- expect(_.transformToUserField('Owner.FirstName')).toBe('User.FirstName');
- expect(_.transformToUserField('Manager.FirstName')).toBe('User.FirstName');
- expect(_.transformToUserField('CreatedBy.FirstName')).toBe('User.FirstName');
- expect(_.transformToUserField('LastModifiedBY.area__c')).toBe('User.area__c');
-
-})
-
-test('The "transformToId" function should add "Id" at the end of the field name', () => {
- expect(_.transformToId('Owner.Manager')).toBe('Owner.ManagerId');
-})
-
-test('The "replaceRwithC" function should replace __r with __c', () => {
- expect(_.replaceRwithC('Owner.custom__r')).toBe('Owner.custom__c');
- //upper case
- expect(_.replaceRwithC('Owner.custom__R')).toBe('Owner.custom__c');
-})
-
-test('Custom Metadata is determined by the presence of the word __MDT anywhere in the field name', () => {
- expect(_.isCustomMetadata(`$CustomMetadata.Trigger_Context_Status__mdt.SRM_Metadata_c.Enable_After_Insert__c`)).toBe(true);
- //upper case
- expect(_.isCustomMetadata(`$CustomMetadata.Trigger_Context_Status__mDT.SRM_Metadata_c.Enable_After_Insert__c`)).toBe(true);
-})
-
-test('Custom Metadata should be converted to both custom fields and metadata types', () => {
-
- let field = '$CustomMetadata.Trigger_Context_Status__mdt.SRM_Metadata_c.Enable_After_Insert__c';
- let value = _.parseCustomMetadata(field)
-
- expect(value.length).toBe(3);
-
- value.forEach(val => {
-
- if(val.type == ValueType.CUSTOM_FIELD){
- expect(val.instance).toBe('Trigger_Context_Status__mdt.Enable_After_Insert__c')
- }
-
- if(val.type == ValueType.CUSTOM_METADATA_TYPE_RECORD){
- expect(val.instance).toBe('Trigger_Context_Status__mdt.SRM_Metadata_c')
- }
-
- if(val.type == ValueType.CUSTOM_METADATA_TYPE){
- expect(val.instance).toBe('Trigger_Context_Status__mdt')
- }
-
- })
-})
-
-test('Custom Labels are determined by the $Label prefix', () => {
- expect(_.isCustomLabel(`$Label.SomeName`)).toBe(true);
- //upper case
- expect(_.isCustomLabel(`$LaBEL.SomeName`)).toBe(true);
-})
-
-
-test('Custom Labels should be parsed by removing the $Label prefix and adding the correct ValueType', () => {
-
- let value = _.parseCustomLabel(`$Label.SomeName`);
-
- expect(value).toHaveProperty('instance','SomeName')
- expect(value).toHaveProperty('type',ValueType.CUSTOM_LABEL);
+test('Word should be converted to upper case',() =>{
+ expect(_.$('hi')).toBe('HI');
})
-
-test('Custom Settings are determined by the $Setup prefix', () => {
- expect(_.isCustomSetting(`$Setup.SomeName`)).toBe(true);
- //upper case
- expect(_.isCustomSetting(`$SeTUP.SomeName`)).toBe(true);
+test('Parts should return the parts based on a dot delimeter', () => {
+ expect(_.parts(fieldName)).toEqual(expect.arrayContaining(fieldNameParts));
})
-test('Custom Settings should be parsed by removing the $Setting prefix and adding the correct ValueType', () => {
-
- let types = _.parseCustomSetting(`$Setup.My_Setting__c.my_field__c`);
-
- let expected = [
- {
- type : ValueType.CUSTOM_FIELD,
- instance:'My_Setting__c.my_field__c'
- },
- {
- type : ValueType.CUSTOM_SETTING,
- instance:'My_Setting__c'
- }
- ]
-
- expect(types).toEqual(expect.arrayContaining(expected));
-
-})
-
-test('Object Types are determined by the $ObjectType prefix', () => {
- expect(_.isObjectType(`$ObjectType.Center__c.Fields.My_text_field__c`)).toBe(true);
- //upper case
- expect(_.isObjectType(`$ObjectTYPE.Center__c.Fields.My_text_field__c`)).toBe(true);
-})
-
-test('Object Types are parsed by removing the unnecessary prefixes and returning the field API name', () => {
-
- let types = _.parseObjectType(`$ObjectType.Center__c.Fields.My_text_field__c`);
-
- let expected = [
- {
- instance:'Center__c.My_text_field__c',
- type:ValueType.CUSTOM_FIELD
- },
- {
- instance:'Center__c',
- type:ValueType.CUSTOM_OBJECT
- }
- ]
-
- expect(types).toEqual(expect.arrayContaining(expected));
-
-
-})
-
-test('A field is considered a relationship field if there is a dot in between' ,() => {
-
- expect(_.isRelationshipField('Account.Name')).toBe(true);
- expect(_.isRelationshipField('Name')).toBe(false);
-
-})
-
-test('The "removePrefix" function should remove the $ character' ,() => {
-
- expect(_.removePrefix('$Organization.Name')).toBe('Organization.Name');
- expect(_.removePrefix('User.RoleId')).toBe('User.RoleId');
-
-})
-
-test('Certain prefixes should be considered of a special type' ,() => {
-
- expect(_.isSpecialPrefix('$Organization')).toBe(true);
- expect(_.isSpecialPrefix('$PROfile')).toBe(true);
- expect(_.isSpecialPrefix('$ObjectType')).toBe(false);
-
-})
-
-test('If a field ends in ParentId, it should be considered a parent field' ,() => {
-
- expect(_.isParentField('Account.Parent')).toBe(false);
- expect(_.isParentField('Account.parEnTid')).toBe(true);
-
-})
-
-test('The word "parent" in a custom field should determine that this is a parent relationship' ,() => {
-
- expect(_.isParent('ParentId')).toBe(false);
- expect(_.isParent('Parent')).toBe(true);
-
-})
-
-test('Parse object should determine if the object is standard or custom' ,() => {
-
- let result = _.parseObject('Account');
-
- let expected = {
- instance:'Account',
- type:ValueType.STANDARD_OBJECT
- }
-
- expect(result).toEqual(expected);
-
- result = _.parseObject('Account__c');
-
- expected = {
- instance:'Account__c',
- type:ValueType.CUSTOM_OBJECT
- }
-
- expect(result).toEqual(expected);
-
+test('Get object should return the object name', () => {
+ expect(_.getObject(fieldName)).toEqual(fieldNameParts[0]);
})
+test('Get field should return the field name', () => {
+ expect(_.getField(fieldName)).toEqual(fieldNameParts[1]);
+})
\ No newline at end of file