示例#1
0
def set_key(ctx, key, mapfile, map_, raw):
    """populate store"""

    if all([key is None, mapfile is None]):
        raise click.ClickException('Missing --key/-k or --mapfile/-m option')

    provider_def = {'type': STORE_TYPE, 'url': STORE_URL}

    st = load_plugin('store', provider_def)

    mapfile_ = mappyfile.open(mapfile, expand_includes=False)
    try:

        value = (mappyfile.dumps(mapfile_)
                 if map_ else mappyfile.dumps(mapfile_['layers']))

        if raw:
            click.echo(f'Setting {key} in store ({st.url})')
            st.set_key(key, value, raw=True)
        else:
            click.echo(f'Setting geomet-mapfile_{key} in store ({st.url})')
            st.set_key(key, value)
    except StoreError as err:
        raise click.ClickException(err)
    click.echo('Done')
示例#2
0
def test_update_delete_dict():
    d1 = {"__type__": "layer", "name": "Unrated", "metadata": {"__type__": "metadata", "key1": "val1"}}
    print(mappyfile.dumps(d1))
    d2 = {"metadata": {"__delete__": True}}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert "metadata" not in d.keys()
示例#3
0
def test_update_delete_dict():
    d1 = {
        "__type__": "layer",
        "name": "Unrated",
        "metadata": {
            "__type__": "metadata",
            "key1": "val1"
        }
    }
    print(mappyfile.dumps(d1))
    d2 = {"metadata": {"__delete__": True}}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert "metadata" not in d.keys()
示例#4
0
def test_update_delete():
    d1 = {"__type__": "layer", "name": "Unrated", "styles": [{"__type__": "style", "color": "#888888"}]}
    d2 = {"name": "Unrated", "styles": [{"__delete__": True}]}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert len(d["styles"]) == 0
 def __call__(self, map_file: types.Mapfile):
     backend_file = mappyfile.loads(self.template)
     backend_file.update(self.map_file_to_dict(map_file))
     errors = mappyfile.validate(backend_file)
     if errors:
         raise Exception(errors)
     return mappyfile.dumps(backend_file)
示例#6
0
def test_double_error():

    s = """MAP
    NAME "sample"
    STATUS ON
    SIZE 600 400
    SYMBOLSET "../etc/symbols.txt"
    EXTENT -180 -90 180
    UNITS DD
    SHAPEPATH "../data"
    IMAGECOLOR 255 255 256
    FONTSET "../etc/fonts.txt"
    WEB
        IMAGEPATH "/ms4w/tmp/ms_tmp/"
        IMAGEURL "/ms_tmp/"
    END
    LAYER
        NAME "global-raster"
        TYPE RASTER
        STATUS DEFAULT
        DATA "bluemarble.gif"
    END
END"""

    d = mappyfile.loads(s, include_position=True)
    # print(json.dumps(d, indent=4))
    v = Validator()
    errors = v.validate(d, add_comments=True)
    # print(json.dumps(d, indent=4))
    # print(errors)
    for e in errors:
        print(e)
    assert(len(errors) == 2)
    print(mappyfile.dumps(d))
示例#7
0
def test_featurecollection():
    gj = get_geojson("FeatureCollection.json")
    layer = mappyfile_geojson.convert(gj)
    print(json.dumps(layer, indent=4))
    s = mappyfile.dumps(layer)
    print(s)
    assert s == """LAYER
示例#8
0
def test_double_error():

    s = """MAP
    NAME "sample"
    STATUS ON
    SIZE 600 400
    SYMBOLSET "../etc/symbols.txt"
    EXTENT -180 -90 180
    UNITS DD
    SHAPEPATH "../data"
    IMAGECOLOR 255 255 256
    FONTSET "../etc/fonts.txt"
    WEB
        IMAGEPATH "/ms4w/tmp/ms_tmp/"
        IMAGEURL "/ms_tmp/"
    END
    LAYER
        NAME "global-raster"
        TYPE RASTER
        STATUS DEFAULT
        DATA "bluemarble.gif"
    END
END"""

    d = mappyfile.loads(s, include_position=True)
    # print(json.dumps(d, indent=4))
    v = Validator()
    errors = v.validate(d, add_comments=True)
    # print(json.dumps(d, indent=4))
    # print(errors)
    for e in errors:
        print(e)
    assert (len(errors) == 2)
    print(mappyfile.dumps(d))
示例#9
0
def test_line_position_mutlilines():

    s = """MAP
    NAME "sample"
    LAYER
        NAME "test"
        STATUS DEFAULT
        DATA "SELECT GEOM
        FROM
        TABLE"
        TYPE LINEX
    END
END"""

    p = Parser()
    ast = p.parse(s)
    print(ast)

    d = mappyfile.loads(s, include_position=True)
    v = Validator()
    errors = v.validate(d, add_comments=True)
    print(json.dumps(d, indent=4))
    # print(errors)
    for e in errors:
        print(e)
    assert (len(errors) == 1)
    err = errors[0]
    assert (err["line"] == 9)
    assert (err["column"] == 9)
    print(mappyfile.dumps(d))
示例#10
0
def test_update_add_item():
    d1 = {"__type__": "layer", "name": "Unrated", "styles": [{"__type__": "style", "color": "#888888"}]}
    d2 = {"name": "Unrated", "styles": [None, {"__type__": "style", "color": [0, 0, 255]}]}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert d["styles"][1]["color"] == [0, 0, 255]
示例#11
0
def test_polygon():
    gj = get_geojson("Polygon.json")
    layer = mappyfile_geojson.convert(gj)
    print(json.dumps(layer, indent=4))
    s = mappyfile.dumps(layer)
    print(s)
    assert s == """LAYER
示例#12
0
def test_update_list():
    d1 = {"__type__": "layer", "name": "Unrated", "styles": [{"__type__": "style", "color": "#888888"}]}
    d2 = {"name": "Unrated", "styles": [{"color": [255, 255, 0]}]}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert d["styles"][0]["color"] == [255, 255, 0]
示例#13
0
def test_dumps():

    s = '''MAP NAME "TEST" END'''

    d = mappyfile.loads(s)
    output = mappyfile.dumps(d, indent=1, spacer="\t", newlinechar=" ")
    print(output)
    assert output == 'MAP 	NAME "TEST" END'
示例#14
0
def test_includes_nested_path():
    p = Parser()

    ast = p.parse_file('./tests/samples/include1_nested_path.map')
    m = MapfileToDict()

    d = (m.transform(ast))  # works
    print(mappyfile.dumps(d))
示例#15
0
def test_includes_nested_path():
    p = Parser()

    ast = p.parse_file('./tests/samples/include1_nested_path.map')
    m = MapfileToDict()

    d = (m.transform(ast))  # works
    print(mappyfile.dumps(d))
示例#16
0
def test_non_ascii():
    p = Parser()

    ast = p.parse_file('./tests/samples/non_ascii.map')
    m = MapfileToDict()

    d = (m.transform(ast))  # works
    print(mappyfile.dumps(d))
示例#17
0
def test_include_from_filehandle():

    fn = './tests/samples/include1.map'

    with open(fn) as f:
        d = mappyfile.load(f)
        assert d["name"] == "include_test"
        print(mappyfile.dumps(d))
示例#18
0
def test_non_ascii():
    p = Parser()

    ast = p.parse_file('./tests/samples/non_ascii.map')
    m = MapfileToDict()

    d = (m.transform(ast))  # works
    print(mappyfile.dumps(d))
示例#19
0
def test_update_list_second_item():
    # test that a None type can be passed
    d1 = {"__type__": "layer", "name": "Unrated", "styles": [{"__type__": "style", "color": "#888888"}, {"__type__": "style", "color": "#888888"}]}
    d2 = {"name": "Unrated", "styles": [None, {"color": [255, 255, 0]}]}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert d["styles"][1]["color"] == [255, 255, 0]
示例#20
0
def test_includes():
    p = Parser()

    ast = p.parse_file('./tests/samples/include1.map')
    m = MapfileToDict()

    d = (m.transform(ast))  # works
    print(mappyfile.dumps(d))
    assert d["name"] == "include_test"
 def changeLayers(self, idx):
     layer = self.cb_layers.itemData(idx)
     if layer:
         self.title_.setText(layer["config"]["title"])
         self.img_layer.setPixmap(QPixmap(layer["config"]["icon"]))
         clayer = deepcopy(layer)
         del clayer["config"]
         self.txt_mapfile_layer.setPlainText(mappyfile.dumps(clayer))
     else:
         self.img_layer.setPixmap(QPixmap())
示例#22
0
def test_class():
    # START OF ADD CLASS EXAMPLE
    # find a layer using its name
    layer = mappyfile.find(mapfile["layers"], "name", "sea")

    new_class_string = """
    CLASS
        NAME 'highlights'
        STYLE
            COLOR 107 208 107
            OUTLINECOLOR 2 2 2
            WIDTH 1
        END
    END
    """

    new_class = mappyfile.loads(new_class_string)
    layer["classes"].insert(1,
                            new_class)  # can insert the new class at any index
    print(mappyfile.dumps(mapfile))

    # END OF ADD CLASS EXAMPLE
    assert (layer['classes'][1]['name'] == "highlights")

    # multiple classes
    # define all classes in a single string TODO - allow on single line
    classes = """
    CLASS 
	    NAME 'The World' 
	    STYLE 
        OUTLINECOLOR 0 255 0
        END
    END
	CLASS 
	    NAME 'Roads' 
	    STYLE
        OUTLINECOLOR 0 0 0
        END
    END
	"""
    # parse the string and replace the existing classes for the layer
    layer["classes"] = mappyfile.loads(classes)
    print(mappyfile.dumps(mapfile))
示例#23
0
def test_class():
    # START OF ADD CLASS EXAMPLE
    # find a layer using its name
    layer = mappyfile.find(mapfile["layers"], "name", "sea")

    new_class_string = """
    CLASS
        NAME 'highlights'
        STYLE
            COLOR 107 208 107
            OUTLINECOLOR 2 2 2
            WIDTH 1
        END
    END
    """

    new_class = mappyfile.loads(new_class_string)
    layer["classes"].insert(1, new_class) # can insert the new class at any index
    print(mappyfile.dumps(mapfile))

    # END OF ADD CLASS EXAMPLE
    assert(layer['classes'][1]['name'] == "highlights")

    # multiple classes
	# define all classes in a single string TODO - allow on single line
    classes = """
    CLASS 
	    NAME 'The World' 
	    STYLE 
        OUTLINECOLOR 0 255 0
        END
    END
	CLASS 
	    NAME 'Roads' 
	    STYLE
        OUTLINECOLOR 0 0 0
        END
    END
	"""
    # parse the string and replace the existing classes for the layer
    layer["classes"] = mappyfile.loads(classes)
    print(mappyfile.dumps(mapfile))
示例#24
0
def test_adding_layers_to_empty():
    """
    Test adding layers when the layers object has not yet been created
    """
    m = mappyfile.loads("MAP END")
    lyr = mappyfile.loads("LAYER TYPE POLYGON NAME 'TEST' END")

    assert len(m["layers"]) == 0
    m["layers"].insert(0, lyr)
    assert len(m["layers"]) == 1
    print(mappyfile.dumps(m))
示例#25
0
def test_dump_with_end_comments():

    s = '''MAP NAME "TEST" END'''

    d = mappyfile.loads(s)
    output = mappyfile.dumps(d,
                             indent=1,
                             spacer="\t",
                             newlinechar=" ",
                             end_comment=True)
    print(output)
    assert output == 'MAP 	NAME "TEST" END # MAP'
示例#26
0
def test_update_delete_root_object():
    d1 = {
        "__type__": "layer",
        "name": "Unrated",
        "styles": [{
            "__type__": "style",
            "color": "#888888"
        }]
    }
    d2 = {"__delete__": True}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    assert output == ""
示例#27
0
def test_includes_relative_path():
    """
    File location can be given as a full path to the file, or (in MapServer >= 4.10.1) as a
    path relative to the mapfile.
    http://mapserver.org/mapfile/include.html
    """
    p = Parser()

    ast = p.parse_file('./tests/samples/include4.map')
    m = MapfileToDict()

    d = (m.transform(ast))  # works
    print(mappyfile.dumps(d))
示例#28
0
def test_metadata_duplicated_key_comment():

    txt = """METADATA
        'wms_title' 'Title1' # title1
        'wms_title' 'Title2' # title2
END"""
    d = mappyfile.loads(txt, include_comments=True, include_position=False)
    s = mappyfile.dumps(d, indent=0, quote="'", newlinechar="\n")
    expected = """METADATA
'wms_title' 'Title2' # title2
END"""

    assert s == expected
示例#29
0
def test_includes_relative_path():
    """
    File location can be given as a full path to the file, or (in MapServer >= 4.10.1) as a
    path relative to the mapfile.
    http://mapserver.org/mapfile/include.html
    """
    p = Parser()

    ast = p.parse_file('./tests/samples/include4.map')
    m = MapfileToDict()

    d = (m.transform(ast))  # works
    print(mappyfile.dumps(d))
def test():
    mapfile = mappyfile.load("./docs/examples/raster.map")
    # START OF API EXAMPLE
    # update the map name
    mapfile["name"] = "MyNewMap"

    # update a layer name
    layers = mapfile["layers"]
    layer = layers[0]
    layer["name"] = "MyLayer"

    # update the error file path in the map config section
    # note key names currently need to be lower case

    mapfile["config"]["ms_errorfile"] = "/ms4w/tmp/ms_error.txt"
    mapfile["config"]["ON_MISSING_DATA"] = "IGNORE"

    # update the web metadata settings
    # currently we need to add quotes for non-keyword keys and values

    mapfile["web"]["metadata"]["'wms_format'"] = "'image/png'"
    print(mappyfile.dumps(mapfile["web"])) # print out just the WEB section

    # alternatively we can parse the Mapfile syntax and load it directly

    s = """
        METADATA
            'wms_enable_request' '*'
            'wms_feature_info_mime_type' 'text/html'
            'wms_format' 'image/jpg'
        END"""

    metadata = mappyfile.loads(s)
    mapfile["web"]["metadata"] = metadata
    print(mappyfile.dumps(mapfile))

    # END OF API EXAMPLE
    assert(layer["name"] == "MyLayer")
    assert(mapfile["web"]["metadata"]["'wms_format'"]  == "'image/jpg'")
示例#31
0
def test_update_delete():
    d1 = {
        "__type__": "layer",
        "name": "Unrated",
        "styles": [{
            "__type__": "style",
            "color": "#888888"
        }]
    }
    d2 = {"name": "Unrated", "styles": [{"__delete__": True}]}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert len(d["styles"]) == 0
示例#32
0
def test_update_list():
    d1 = {
        "__type__": "layer",
        "name": "Unrated",
        "styles": [{
            "__type__": "style",
            "color": "#888888"
        }]
    }
    d2 = {"name": "Unrated", "styles": [{"color": [255, 255, 0]}]}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    print(output)
    assert d["styles"][0]["color"] == [255, 255, 0]
示例#33
0
def parse(mf):
    m = mappyfile.open(mf, expand_includes=False)
    s = mappyfile.dumps(m)

    # if PY2:
    #     s = mappyfile.dumps(m)
    #     f = tempfile.NamedTemporaryFile(delete=False)
    #     f.write(s.encode("utf-8"))
    # else:
    #     f = tempfile.NamedTemporaryFile(delete=False, mode="w", encoding="utf-8")
    #     mappyfile.dump(m, f)

    # f.close()
    return s
示例#34
0
def parse(mf):
    m = mappyfile.open(mf, expand_includes=False)
    s = mappyfile.dumps(m)

    # if PY2:
    #     s = mappyfile.dumps(m)
    #     f = tempfile.NamedTemporaryFile(delete=False)
    #     f.write(s.encode("utf-8"))
    # else:
    #     f = tempfile.NamedTemporaryFile(delete=False, mode="w", encoding="utf-8")
    #     mappyfile.dump(m, f)

    # f.close()
    return s
示例#35
0
def get_lyr_mapfile():
    # mapfile = mappyfile.open("basic_mapfile.map")
    #
    # update the map name
    # mapfile["name"] = "MyNewMap"
    new_layer_string = """
LAYER
    NAME 'land'
    TYPE POLYGON
    DATA '../data/vector/naturalearth/ne_110m_land'
    CLASS
        STYLE
            COLOR 107 208 107
            OUTLINECOLOR 2 2 2
            WIDTH 1
        END
    END
END
"""
    # layers = mapfile["layers"]
    new_layer = mappyfile.loads(new_layer_string)
    # print(mappyfile.dumps(new_layer['class']))
    classes = new_layer["classes"]
    new_layer['name'] = 'the_lyr_name'
    for c in classes:
        print('aa')
        print(mappyfile.dumps(c['styles'][0]))

        for x in c['styles']:
            print(x['color'])
            x['color'] = [1, 1, 1]
    # layers.insert(0, new_layer) # insert the new layer at any index in the Mapfile
    # for l in layers:
    #     print("{} {}".format(l["name"], l["type"]))
    # print(mappyfile.dumps(mapfile, indent=1, spacer="\t"))
    # mapfile = mappyfile.open("xx_out.map")
    print(mappyfile.dumps(new_layer, indent=1, spacer="    "))
示例#36
0
def test():
    mapfile = mappyfile.open("./docs/examples/raster.map")
    # START OF API EXAMPLE
    # update the map name
    mapfile["name"] = "MyNewMap"

    # update a layer name
    layers = mapfile["layers"]
    layer = layers[0]
    layer["name"] = "MyLayer"

    # update the error file path in the map config section
    # note key names can be lower or upper case

    mapfile["config"]["ms_errorfile"] = "/ms4w/tmp/ms_error.txt"

    # update the web metadata settings

    mapfile["web"]["metadata"]["wms_format"] = "image/png"
    print(mappyfile.dumps(mapfile["web"]))  # print out just the WEB section

    # alternatively we can parse the Mapfile syntax and load it directly

    s = """
        METADATA
            'wms_enable_request' '*'
            'wms_feature_info_mime_type' 'text/html'
            'wms_format' 'image/jpg'
        END"""

    metadata = mappyfile.loads(s)
    mapfile["web"]["metadata"] = metadata
    print(mappyfile.dumps(mapfile))

    # END OF API EXAMPLE
    assert (layer["name"] == "MyLayer")
    assert (mapfile["web"]["metadata"]["wms_format"] == "image/jpg")
示例#37
0
def test_metadata_unquoted_comment():

    txt = """
    METADATA
      WMS_TITLE "Minor Civil Divisions" # comment
    END
    """

    d = mappyfile.loads(txt, include_comments=True, include_position=False)
    s = mappyfile.dumps(d, indent=0, quote='"', newlinechar="\n")
    expected = """METADATA
"wms_title" "Minor Civil Divisions" # comment
END"""

    assert s == expected
示例#38
0
def test_single_layer_data():

    s = u"""
    LAYER
        DATA "dataset1"
    END
    """
    jsn = mappyfile.loads(s)
    print(json.dumps(jsn, indent=4))
    jsn["data"][0] = "dataset1"
    print(mappyfile.dumps(jsn))

    print(output(s, schema_name="layer"))
    exp = u"LAYER DATA 'dataset1' END"
    assert (output(s, schema_name="layer") == exp)
示例#39
0
def test_update():
    s1 = """
    MAP
        LAYER
            NAME "Layer1"
            TYPE POLYGON
        END
        LAYER
            NAME "Layer2"
            TYPE POLYGON
            CLASS
                NAME "Class1"
                COLOR 255 255 0
            END
        END
    END
    """

    d1 = mappyfile.loads(s1)

    s2 = """
    MAP
        LAYER
            NAME "Layer1"
            TYPE POLYGON
        END
        LAYER
            NAME "LayerNew"
            TYPE POINT
            CLASS
                NAME "Class1"
                COLOR 0 0 255
            END
            CLASS
                NAME "Class2"
                COLOR 0 0 0
            END
        END
    END
    """

    d2 = mappyfile.loads(s2)
    d = mappyfile.update(d1, d2)

    output = mappyfile.dumps(d)
    print(output)
示例#40
0
def test_update():
    s1 = """
    MAP
        LAYER
            NAME "Layer1"
            TYPE POLYGON
        END
        LAYER
            NAME "Layer2"
            TYPE POLYGON
            CLASS
                NAME "Class1"
                COLOR 255 255 0
            END
        END
    END
    """

    d1 = mappyfile.loads(s1)

    s2 = """
    MAP
        LAYER
            NAME "Layer1"
            TYPE POLYGON
        END
        LAYER
            NAME "LayerNew"
            TYPE POINT
            CLASS
                NAME "Class1"
                COLOR 0 0 255
            END
            CLASS
                NAME "Class2"
                COLOR 0 0 0
            END
        END
    END
    """

    d2 = mappyfile.loads(s2)
    d = mappyfile.update(d1, d2)

    output = mappyfile.dumps(d)
    print(output)
示例#41
0
def test_cluster_validation_fail():

    s = u"""
    MAP
        LAYER
            CLUSTER
                MAXDISTANCE 50
                REGION "ELLIPSEZ"
            END
        END
    END
    """

    d = mappyfile.loads(s, include_position=True)
    v = Validator()
    errors = v.validate(d, add_comments=True)
    print(mappyfile.dumps(d))
    assert len(errors) == 1
def changeLayerRange(layer, layerRange, userFString):

    userInitMap = f'{os.path.join(current_app.config["PERSONAL_FOLDERS_LOCATION"], userFString, "mapFiles/sentinel_index.map")}'
    userModifiedMap = f'{os.path.join(current_app.config["PERSONAL_FOLDERS_LOCATION"], userFString, "mapFiles/mapFilesModified", "sentinel_index_modified.map")}'

    layerRangeJSON = json.loads(layerRange.replace("\'", "\""))
    mapfile = mappyfile.open(userInitMap)

    # update the map name
    mapfile['name'] = 'sentinel_index_modified.map'

    ## Check for existing map file and delete in it exists.
    if os.path.exists(userModifiedMap):
        os.remove(userModifiedMap)

    # find a layer using its name
    layer = mappyfile.find(mapfile["layers"], "name", layer)
    # get class breaks and class colours from layerRange
    classBreaks = layerRangeJSON['classBreaks']
    classColours = layerRangeJSON['classColours']
    # define new mapfile classes empty string
    completeNewClassString = ''
    # iteraterate over class breaks and colours and insert their values to default class string. At the end append current string to string containing all classes
    for breaks,colours in zip(classBreaks,classColours):
        newClassString = f"""
    CLASS
        EXPRESSION ([pixel] >= {breaks[0]} AND [pixel] < {breaks[1]})
        STYLE
            COLORRANGE {colours[0][0]} {colours[0][1]} {colours[0][2]} {colours[1][0]} {colours[1][1]} {colours[1][2]}
            RANGEITEM 'pixel'
        END
    END
"""
        completeNewClassString += newClassString
    # load class string to map object
    newClasses = mappyfile.loads(completeNewClassString)
    layer["classes"] = newClasses
    # save new map file to disk and return path to it
    modifiedMapFile = mappyfile.dumps(mapfile)
    with open(userModifiedMap, "w")as mf:
        for li in modifiedMapFile:
            mf.write(li)
        mf.close 
    return {"modifiedMapFile": userModifiedMap}
示例#43
0
def test_metadata_comment():

    txt = """MAP
    # metadata comment
    # on two lines
    METADATA
        # another comment
        'wms_title' 'Test simple wms' # prop comment
    END
    END"""
    d = mappyfile.loads(txt, include_comments=True, include_position=False)
    # print(json.dumps(d, indent=4))
    s = mappyfile.dumps(d, indent=0, quote="'", newlinechar="\n")
    # print(s)
    expected = """MAP
# metadata comment
# on two lines
METADATA
'wms_title' 'Test simple wms' # prop comment # another comment
END
END"""
    assert s == expected
示例#44
0
def test_update_delete_root_object():
    d1 = {"__type__": "layer", "name": "Unrated", "styles": [{"__type__": "style", "color": "#888888"}]}
    d2 = {"__delete__": True}
    d = mappyfile.update(d1, d2)
    output = mappyfile.dumps(d)
    assert output == ""