Repository: joshtemple/lkml

Issue:
Simple Parser unnests `dimensions` and `measures` in `query` fields
For [query](https://docs.looker.com/reference/explore-params/query) fields, the dimensions and measures keys are special - they are kept in plural form, with a list as the value.

When the simple parser parses this field, it sees that it's a pluralized key, and unnests them. Example:
```
In [98]: lkml.dump(
    ...:   {
    ...:     "explores": [
    ...:       {
    ...:         "name": "queried_explore",
    ...:         "queries": [
    ...:           {
    ...:             "dimensions": ["first_dim"],
    ...:             "measures": ["first_meas"],
    ...:             "pivots": ["first_pivot"],
    ...:             "name": "aquery"
    ...:           }
    ...:         ]
    ...:       }
    ...:     ]
    ...:   }
    ...: )
Out[98]: 'explore: queried_explore {\n  query: aquery {\n    dimension: first_dim\n    measure: first_meas\n    pivots: [first_pivot]\n  }\n}'
```

Discussion:
joshtemple: Thanks @fbertsch! Seems like there was an issue with CI not triggering for this PR. I've fixed it on `master`, do you mind rebasing this branch off the latest version of `master` and force-pushing to update this PR?

Patch:
diff --git a/lkml/simple.py b/lkml/simple.py
index 1ad2c77..39031ca 100644
--- a/lkml/simple.py
+++ b/lkml/simple.py
@@ -210,14 +210,21 @@ class DictParser:
         parent key. If its parent key is `access_grant`, it is a list and cannot be
         repeated. Otherwise, it can be repeated.
 
+        The parent key `query` is also a special case, where children are kept as lists.
+        See issue #53.
+
         Args:
             key: The name of the key to test.
 
         """
         singular_key = singularize(key)
-        return singular_key in PLURAL_KEYS and not (
-            singular_key == "allowed_value"
-            and self.parent_key.rstrip("s") == "access_grant"
+        return (
+            singular_key in PLURAL_KEYS
+            and not (
+                singular_key == "allowed_value"
+                and self.parent_key.rstrip("s") == "access_grant"
+            )
+            and not (self.parent_key == "query")
         )
 
     def resolve_filters(self, values: List[dict]) -> Union[List[BlockNode], ListNode]:


Test patch:
diff --git a/tests/test_simple.py b/tests/test_simple.py
index 273def6..2c5a748 100644
--- a/tests/test_simple.py
+++ b/tests/test_simple.py
@@ -262,6 +262,28 @@ def test_parse_top_level_pairs(parser):
     )
 
 
+def test_parse_query(parser):
+    obj = {
+        "queries": [
+            {
+                "name": "query_one",
+                "dimensions": ["dimension_one", "dimension_two"],
+                "measures": ["measure_one"]
+            }
+        ]
+    }
+    node = parser.parse(obj)
+    result = str(node)
+    assert result == "\n".join(
+        (
+            "query: query_one {",
+            "  dimensions: [dimension_one, dimension_two]",
+            "  measures: [measure_one]",
+            "}",
+        )
+    )
+
+
 def test_resolve_filters_filter_only_field(parser):
     nodes = parser.resolve_filters(
         [{"name": "filter_a", "type": "string"}, {"name": "filter_b", "type": "number"}]