用于排序和区分嵌套词典和列表的工具。
ndl-tools的Python项目详细描述
ndl工具
用于排序和区分嵌套词典和列表的工具。在
该包的重点是支持API测试。散列两个对象树或 用嵌套字典来比较它们的效果非常好 实际上是相等的。如果他们不平等,找出为什么会变得相当乏味。在
这些是相等的吗?在
obj1={"a":1,"b":2}obj2={"b":2,"a":1}
如果一个集合在转换为JSON时被映射到一个列表中呢。在
^{pr2}$fromdatetimeimportdatetimeobj1={"start_date":datetime.date(1999,1,1)}obj2={"start_date":datetime.date(2020,8,19)}
字典的分类和比较是不错的,但是当一本字典被分类和比较时,它会变得混乱 值的另一个字典、列表或集合。列表大小写是否需要排序 取决于对象的上下文以及它是列表还是集合。最后,约会一号 很难在测试用例中保持最新,因为日期不断变化。如果你 可以用冰枪之类的东西来及时返回,但是如果有效载荷来自外部 服务可能会一团糟。在
概念
Term | Definition |
---|---|
Differ | Entry point to support diff of two Nested-Dict-Lists (NDL). |
DiffResult | Result of calling diff() in a Differ object. It acts like a bool for simple asserts, but also provides a two column colored difference of the two NDL. |
ListSorter | Classes that can be selectively applied to lists in the NDL either sort or not sort a list. |
Normalizer | Classes that can be applied to leaf elements to transform them to match from the left and right NDLs. |
Selector | Classes used to select what elements in the traversal of the NDL a given ListSorter or Normalizer is applied. |
Sorter | Entry point to NDL sorter functionality. This normally isn't used directly as it sits behind the Differ. |
示例
浮点精度
fromndl_toolsimportDifferOBJ_1={"a":1.0,"b":2.01}OBJ_2={"a":1.01,"b":2.011}deffloat_mismatch():differ=Differ()result=differ.diff(OBJ_1,OBJ_2)assertnotresultprint(result.support)
注意不同之处的亮点。红色表示删除了某些内容,蓝色表示删除了 一些东西被改变了,黄色的东西被添加了。在
匹配
当我们进行diff时,让我们应用FloatRoundNormalizer,看看是否可以使ndl匹配。在
fromndl_toolsimportDiffer,FloatRoundNormalizerOBJ_1={"a":1.0,"b":2.01}OBJ_2={"a":1.01,"b":2.011}deffloat_match():differ=Differ()float_round_normalizer=FloatRoundNormalizer(places=1)result=differ.diff(OBJ_1,OBJ_2,normalizers=[float_round_normalizer])assertresultprint(result.support)
选择器以应用不同的nomalizer
fromndl_toolsimportDiffer,FloatRoundNormalizer,ListLastComponentSelectorOBJ_1={"a":1.0,"b":2.01}OBJ_2={"a":1.01,"b":2.011}deffloat_two_precision_match():differ=Differ()# Normalize the 'a' element to 1 decimal place.a_selector=ListLastComponentSelector(component_names=["a"])one_float_round_normalizer=FloatRoundNormalizer(places=1,selectors=[a_selector])# Normalize the 'b' element to 2 decimal places.b_selector=ListLastComponentSelector(component_names=["b"])two_float_round_normalizer=FloatRoundNormalizer(places=2,selectors=[b_selector])result=differ.diff(OBJ_1,OBJ_2,normalizers=[two_float_round_normalizer,one_float_round_normalizer])assertresultprint(result.support)
每个规格化器都可以有一个不同的选择器,或者使用默认的选择器 所有元素。将按顺序调用规范化器列表,直到一个规范化元素或全部 正常化者已经筋疲力尽。有一门艺术可以解决如何将 规范化器和选择器需要两个NDL进行匹配。如果你开始 当你有很多这样的想法时,也许是时候考虑做些什么了 在比较它们之前,先对NDL进行准备。在
标准化器
规范化器设计为易于扩展。签出现有的Normalizers 你可以很容易地看到扩展这些来支持指数,日期。。。在
^{tb2}$建立你自己的标准化器有一些乐趣。它只在init()和_normalize()方法中使用几行代码。在
[!WARNING] If a normalizer was applied to an element, but doesn't actually normalize it, the normalizer should raise NotNormalizedError()
选择器
选择器确定它们所附加的规范化器是否将应用于给定元素。阿盖恩 有一门艺术可以计算出所需的最小数量或仍然清楚的最小数量。在
虽然这并不是重写上面将“a”和“b”舍入到的示例的最有效方法 一个小数位,它显示了如何将多个选择器应用于单个规格化器。在
fromndl_toolsimportDiffer,FloatRoundNormalizer,ListLastComponentSelectorOBJ_1={"a":1.0,"b":2.01}OBJ_2={"a":1.01,"b":2.011}defselector_chaining_match():differ=Differ()a_selector=ListLastComponentSelector(component_names=["a"])b_selector=ListLastComponentSelector(component_names=["b"])float_round_normalizer=FloatRoundNormalizer(places=1,selectors=[a_selector,b_selector])result=differ.diff(OBJ_1,OBJ_2,normalizers=[float_round_normalizer])assertresultprint(result.support)
有一些现成的选择器,但是您应该将自己的选择器子类化以最小化复杂性 你的差异代码。在
Selector | Usage |
---|---|
ListLastComponentSelector | Match the last component in the element path to a list of names. |
ListAnyComponentSelector | Match any component in the element path to a list of names. Good if you want to select a branch and its child elements. |
RegExSelector | Match the element path with the RegEx. |
NegativeSelector | Inverts the selection of the Selector it wraps. |
EndsWithSelector | Match the end of the path. |
列表排序器
ListSorters用于控制列表/集合的排序方式。使用选择器应用 与规范化器相同。你不需要别的东西 这两个提供了ListSorters,但是如果您需要扩展性的话。在
- 项目
标签: