mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +00:00 
			
		
		
		
	(core) Fix lookups in default formulas
Test Plan: TODO Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D2603
This commit is contained in:
		
							parent
							
								
									166143557a
								
							
						
					
					
						commit
						2fbd3f1706
					
				| @ -181,7 +181,6 @@ class DocModel(object): | ||||
|   def __init__(self, engine): | ||||
|     self._engine = engine | ||||
|     global global_docmodel # pylint: disable=global-statement | ||||
|     if not global_docmodel: | ||||
|     global_docmodel = self | ||||
| 
 | ||||
|     # Set of records scheduled for automatic removal. | ||||
|  | ||||
| @ -467,7 +467,7 @@ class Engine(object): | ||||
|     """ | ||||
|     Returns the compute frame currently being computed, or None if there isn't one. | ||||
|     """ | ||||
|     return self._compute_stack[-1] if self._compute_stack else None | ||||
|     return self._compute_stack[-1] if self._compute_stack and self._compute_stack[-1].node else None | ||||
| 
 | ||||
|   def _use_node(self, node, relation, row_ids=[]): | ||||
|     # This is used whenever a formula accesses any part of any record. It's hot code, and | ||||
|  | ||||
| @ -22,9 +22,10 @@ def _make_datetime(value): | ||||
|     raise ValueError('Invalid date %r' % (value,)) | ||||
| 
 | ||||
| def _get_global_tz(): | ||||
|   if docmodel.global_docmodel: | ||||
|     return docmodel.global_docmodel.doc_info.lookupOne(id=1).tzinfo | ||||
|   return moment.TZ_UTC | ||||
|   # If doc_info record is missing (e.g. in tests), default to UTC. We should not return None, | ||||
|   # since that would produce naive datetime objects, which is not what we want. | ||||
|   dm = docmodel.global_docmodel | ||||
|   return (dm.doc_info.lookupOne(id=1).tzinfo if dm else None) or moment.TZ_UTC | ||||
| 
 | ||||
| def _get_tzinfo(zonelabel): | ||||
|   """ | ||||
|  | ||||
							
								
								
									
										129
									
								
								sandbox/grist/test_default_formulas.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								sandbox/grist/test_default_formulas.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | ||||
| import time | ||||
| import logger | ||||
| import testutil | ||||
| import test_engine | ||||
| 
 | ||||
| log = logger.Logger(__name__, logger.INFO) | ||||
| 
 | ||||
| class TestDefaultFormulas(test_engine.EngineTestCase): | ||||
|   sample = testutil.parse_test_sample({ | ||||
|     "SCHEMA": [ | ||||
|       [1, "Customers", [ | ||||
|         [1, "Name",       "Text",           False, "", "", ""], | ||||
|         [2, "Region",     "Ref:Regions",    False, "", "", ""], | ||||
|         [3, "RegName",    "Text",           True,  "$Region.Region", "", ""], | ||||
|         [4, "SalesRep",   "Text",           False, "$Region.Rep", "", ""], | ||||
|         [5, "CID",        "Int",            False, "$id + 1000", "", ""], | ||||
|       ]], | ||||
|       [2, "Regions", [ | ||||
|         [11, "Region",    "Text",           False, "", "", ""], | ||||
|         [12, "Rep",       "Text",           False, "", "", ""] | ||||
|       ]], | ||||
|     ], | ||||
|     "DATA": { | ||||
|       "Customers": [ | ||||
|         ["id","Name",     "Region",   "SalesRep", "CID"], | ||||
|         [1,   "Dolphin",  2,          "Neptune",  0 ], | ||||
|       ], | ||||
|       "Regions": [ | ||||
|         ["id",  "Region",     "Rep"], | ||||
|         [1,     "Pacific",    "Watatsumi"], | ||||
|         [2,     "Atlantic",   "Poseidon"], | ||||
|         [3,     "Indian",     "Neptune"], | ||||
|         [4,     "Arctic",     "Poseidon"], | ||||
|       ], | ||||
|     } | ||||
|   }) | ||||
| 
 | ||||
|   def test_default_formula_plain(self): | ||||
|     self.load_sample(self.sample) | ||||
| 
 | ||||
|     # The defaults don't affect data that's loaded | ||||
|     self.assertTableData("Customers", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID" ], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",         0], | ||||
|     ]) | ||||
| 
 | ||||
|     # Defaults affect new records | ||||
|     self.add_record("Customers", Name="Shark", Region=2) | ||||
|     self.add_record("Customers", Name="Squid", Region=1) | ||||
|     self.assertTableData("Customers", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID"], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",  0], | ||||
|       [2,   "Shark",    2,        "Atlantic",   "Poseidon", 1002],    # New record | ||||
|       [3,   "Squid",    1,        "Pacific",    "Watatsumi",1003],    # New record | ||||
|     ]) | ||||
| 
 | ||||
|     # Changed defaults don't affect previously-added records | ||||
|     self.modify_column('Customers', 'CID', formula='$id + 2000') | ||||
|     self.add_record("Customers", Name="Hammerhead", Region=3) | ||||
|     self.assertTableData("Customers", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID"], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",  0], | ||||
|       [2,   "Shark",    2,        "Atlantic",   "Poseidon", 1002], | ||||
|       [3,   "Squid",    1,        "Pacific",    "Watatsumi",1003], | ||||
|       [4,   "Hammerhead", 3,      "Indian",     "Neptune",  2004],    # New record | ||||
|     ]) | ||||
| 
 | ||||
|     # Defaults don't affect changes to existing records | ||||
|     self.update_record("Customers", 2, Region=3) | ||||
|     self.assertTableData("Customers", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID"], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",  0], | ||||
|       [2,   "Shark",    3,        "Indian",     "Poseidon", 1002],    # Region changed | ||||
|       [3,   "Squid",    1,        "Pacific",    "Watatsumi",1003], | ||||
|       [4,   "Hammerhead", 3,      "Indian",     "Neptune",  2004], | ||||
|     ]) | ||||
| 
 | ||||
| 
 | ||||
|   def test_default_formula_with_lookups(self): | ||||
|     self.load_sample(self.sample) | ||||
|     self.modify_column('Customers', 'RegName', isFormula=False, formula="") | ||||
|     self.modify_column('Customers', 'Region', isFormula=False, | ||||
|         formula="Regions.lookupOne(Region=$RegName)") | ||||
|     self.assertTableData("Customers", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID" ], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",  0], | ||||
|     ]) | ||||
| 
 | ||||
|     # Lookup-based defaults work. | ||||
|     self.add_record("Customers", Name="Shark", RegName="Atlantic") | ||||
|     self.add_record("Customers", Name="Squid", RegName="Pacific") | ||||
|     self.assertTableData("Customers", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID"], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",  0], | ||||
|       [2,   "Shark",    2,        "Atlantic",   "Poseidon", 1002],    # New record | ||||
|       [3,   "Squid",    1,        "Pacific",    "Watatsumi",1003],    # New record | ||||
|     ]) | ||||
| 
 | ||||
|   def test_time_defaults(self): | ||||
|     self.load_sample(self.sample) | ||||
|     self.add_column('Customers', 'AddTime', | ||||
|         type="DateTime:America/Los_Angeles", isFormula=False, formula="NOW()") | ||||
|     self.add_column('Customers', 'AddDate', | ||||
|         type="Date", isFormula=False, formula="TODAY()") | ||||
| 
 | ||||
|     self.assertTableData("Customers", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID",  "AddTime",  "AddDate" ], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",  0,      None,       None      ], | ||||
|     ]) | ||||
|     self.add_record("Customers", Name="Shark", Region=2) | ||||
|     self.add_record("Customers", Name="Squid", Region=1) | ||||
| 
 | ||||
|     now = time.time() | ||||
|     midnight = now - (now % (24*60*60)) | ||||
| 
 | ||||
|     # Check columns except AddTime, which we check separately below. | ||||
|     self.assertTableData("Customers", cols="subset", data=[ | ||||
|       ["id","Name",     "Region", "RegName",    "SalesRep", "CID",  "AddDate"], | ||||
|       [1,   "Dolphin",  2,        "Atlantic",   "Neptune",  0,      None], | ||||
|       [2,   "Shark",    2,        "Atlantic",   "Poseidon", 1002,   midnight],    # New record | ||||
|       [3,   "Squid",    1,        "Pacific",    "Watatsumi",1003,   midnight],    # New record | ||||
|     ]) | ||||
| 
 | ||||
|     # AddTime column is hard to be precise about, check it separately. Note that the timestamp | ||||
|     # does not depend on timezone, and should not change based on the timezone in the column type. | ||||
|     observed_data = self.engine.fetch_table('Customers') | ||||
|     self.assertEqual(observed_data.columns['AddTime'][0], None) | ||||
|     self.assertLessEqual(abs(observed_data.columns['AddTime'][1] - now), 2) | ||||
|     self.assertLessEqual(abs(observed_data.columns['AddTime'][2] - now), 2) | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user