Source code for tests.testJson

'''
Created on 2020-09-12

@author: wf
'''
import unittest
from tests.basetest import Basetest
import json
from lodstorage.sample import Royals,RoyalsORMList,Royal,Cities
from lodstorage.jsonable import JSONAble, Types, JSONAbleList
import time
import tempfile

[docs]class ServerConfig(JSONAble): def __init__(self): pass
[docs]class TestJsonAble(Basetest): ''' test JSON serialization with JsonAble mixin '''
[docs] def setUp(self): super().setUp(debug=False) self.doProfile=True self.maxDiff=None pass
[docs] def testSingleToDoubleQuote(self): jsonStr=''' { "cities": [ { "name": "Upper Hell's Gate" }, { "name": "N'zeto" } ] } ''' listOfDicts=json.loads(jsonStr) dictStr=str(listOfDicts) if self.debug: print(dictStr) jsonStr2=JSONAble.singleQuoteToDoubleQuote(dictStr) if self.debug: print(jsonStr2) self.assertEqual('''{"cities": [{"name": "Upper Hell's Gate"}, {"name": "N'zeto"}]}''',jsonStr2)
[docs] def testSingleQuoteToDoubleQuoteStackoverflow(self): """ see - https://stackoverflow.com/a/63862387/1497139 - https://stackoverflow.com/a/50257217/1497139 """ singleQuotedExamples=[ '''{'cities': [{'name': "Upper Hell's Gate"}, {'name': "N'zeto"}]'''] for example in singleQuotedExamples: if self.debug: print (example) for useRegex in [False,True]: doubleQuoted=JSONAble.singleQuoteToDoubleQuote(example,useRegex=useRegex) if self.debug: print(doubleQuoted) if self.debug: print
[docs] def dumpListOfDicts(self,listOfDicts,limit): if self.debug: for index,record in enumerate(listOfDicts[:limit]): print("%2d:%s" % (index,record))
[docs] def check(self,manager,manager1,listName,debugLimit): ''' check that the list of the two managers are the same ''' d1=manager.__dict__[listName] d2=manager1.__dict__[listName] self.dumpListOfDicts(d1, debugLimit) self.dumpListOfDicts(d2, debugLimit) self.assertEqual(d1,d2)
[docs] def testJsonAble(self): ''' test JSONAble ''' examples=[{ 'manager': Royals(load=True), 'listName': 'royals' }, { 'manager': Cities(load=True), 'listName': 'cities' } ] debugLimit=10 debugChars=debugLimit*100 index=0 for useToJson in [True,False]: for example in examples: starttime=time.time() manager=example['manager'] listName=example['listName'] if useToJson: jsonStr=manager.toJSON() else: jsonStr=manager.asJSON() if self.debug: print(jsonStr[:debugChars]) #print(jsonStr,file=open('/tmp/example%d.json' %index,'w')) index+=1 if self.doProfile: print("->JSON for %d took %7.3f s" % (index, (time.time()-starttime))) self.assertTrue(isinstance(jsonStr,str)) starttime=time.time() jsonDict=json.loads(jsonStr) self.assertTrue(isinstance(jsonDict,dict)) if self.debug: print(str(jsonDict)[:debugChars]) if self.doProfile: print("<-JSON for %d took %7.3f s" % (index, time.time()-starttime)) cls=manager.__class__ types=Types(cls.__name__) types.getTypes(listName,manager.__dict__[listName]) manager1=cls() manager1.fromJson(jsonStr,types=types) self.check(manager,manager1,listName,debugLimit=debugLimit) pass
[docs] def testRoyals(self): ''' test Royals example ''' royals1=Royals(load=True) self.assertEqual(4,len(royals1.royals)) json=royals1.toJSON() if self.debug: print(json) types=Types.forTable(royals1, "royals",debug=True) royals2=Royals() royals2.fromJson(json,types=types) self.assertEqual(4,len(royals2.royals)) if self.debug: print(royals1.royals) print(royals2.royals) self.assertEqual(royals1.royals,royals2.royals)
[docs] def testPluralName(self): royal=Royal() self.assertEqual("Royals",royal.getPluralname())
[docs] def testStoreAndRestore(self): ''' test storing and restoring from a JSON file https://github.com/WolfgangFahl/pyLoDStorage/issues/21 ''' royals1=RoyalsORMList(load=True) jsonFile="/tmp/royals-pylodstorage.json" royals1.storeToJsonFile(jsonFile) royals2=RoyalsORMList() royals2.restoreFromJsonFile(jsonFile) self.assertEqual(4,len(royals2.royals)) for royal in royals2.royals: self.assertTrue(isinstance(royal,Royal)) self.assertEqual("float",type(royal.age).__name__)
[docs] def testIssue22(self): ''' https://github.com/WolfgangFahl/pyLoDStorage/issues/22 Regression: storeToJsonFile and restoreFromJsonFile missing in JSONAble ''' jsonStr="""{ "adminPassword": "tiger2021", "adminUser": "scott", "credentials": [ { "dbname": "doedb", "password": "doesSecret!", "user": "john" } ], "frontendConfigs": [ { "defaultPage": "Frontend", "site": "or", "template": "bootstrap.html", "wikiId": "or" }, { "defaultPage": "Main Page", "site": "cr", "template": "bootstrap.html", "wikiId": "cr" } ], "logo": "https://commons.wikimedia.org/wiki/Category:Mona_Lisa#/media/File:Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg" }""" jsonFilePath=f'{tempfile.gettempdir()}/serverConfig.json' JSONAble.storeJsonToFile(jsonStr, jsonFilePath) serverConfig=ServerConfig() serverConfig.restoreFromJsonFile(jsonFilePath) self.assertTrue(serverConfig.logo.endswith("_retouched.jpg")) self.assertTrue(isinstance(serverConfig.frontendConfigs,list)) self.assertEqual(2,len(serverConfig.frontendConfigs)) serverConfig.storeToJsonFile(jsonFilePath) jsonStr2=JSONAble.readJsonFromFile(jsonFilePath) if self.debug: print(jsonStr2) self.assertEqual(jsonStr,jsonStr2)
[docs] def testRestoreFromJsonStr(self): ''' Tests restoring a JsonAbleList form a json string ''' samples = """ { "countries": [ { "name": "Afghanistan", "wikidataid": "Q889", "coordinates": "34,66", "partOf": null, "level": 3, "locationKind": "Country", "comment": null, "iso": "AF" }, { "name": "United States of America", "wikidataid": "Q30", "coordinates": "39.828175,-98.5795", "partOf": null, "level": 3, "locationKind": "Country", "comment": null, "labels": [ "America", "UNITED STATES OF AMERICA", "USA", "United States", "United States of America (the)" ], "iso": "US" }, { "name": "Australia", "wikidataid": "Q408", "coordinates": "-28,137", "partOf": null, "level": 3, "locationKind": "Country", "comment": null, "labels": [ "AUS" ], "iso": "AU" } ] } """ countryList=JSONAbleList("countries") countryList.restoreFromJsonStr(samples) countries=countryList.countries self.assertTrue(len(countries)==3) countryIds=[x['wikidataid'] for x in countries] self.assertTrue("Q30" in countryIds)
[docs] def testIssue27_Lookup(self): ''' add Lookup map option ''' # first try with List of Dicts royals=Royals(load=True) #print(len(royals.royals)) #print(royals.royals) royalsByNumberInLine,duplicates=royals.getLookup("numberInLine", withDuplicates=False) #print(royalsByNumberInLine) self.assertEqual(0,len(duplicates)) self.assertEqual(4,len(royalsByNumberInLine)) self.assertEqual("Charles, Prince of Wales",royalsByNumberInLine[1]["name"]) # then with list of Entities royalsORM=RoyalsORMList(load=True) royalsByNumberInLine,duplicates=royalsORM.getLookup("numberInLine", withDuplicates=False) self.assertEqual(0,len(duplicates)) self.assertEqual(4,len(royalsByNumberInLine)) self.assertEqual("Charles, Prince of Wales",royalsByNumberInLine[1].name)
[docs] def testIssue30_SampleLimited(self): ''' tests if the json export is correctly limited to the fields that are used in the samples ''' royalDict={"name":"Test royal"} royal=Royal() royal.fromDict(royalDict) # add attributes that are not in the samples royal.__dict__["not_in_samples"]="test" expectedJSON="""{ "name": "Test royal" }""" actualJSON=royal.toJSON(limitToSampleFields=True) self.assertEqual(actualJSON, expectedJSON)
if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main()