okstra 0.113.0 → 0.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.kr.md +2 -2
- package/README.md +2 -2
- package/docs/for-ai/README.md +2 -2
- package/docs/for-ai/skills/{okstra-brief.md → okstra-brief-gen.md} +3 -3
- package/docs/for-ai/skills/okstra-inspect.md +1 -1
- package/docs/kr/architecture.md +11 -11
- package/docs/kr/cli.md +1 -1
- package/docs/kr/follow-ups/2026-07-10-final-report-option-3.md +51 -0
- package/docs/project-structure-overview.md +2 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/report-writer-worker.md +1 -0
- package/runtime/prompts/lead/context-loader.md +2 -2
- package/runtime/prompts/lead/okstra-lead-contract.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +3 -3
- package/runtime/prompts/profiles/implementation-planning.md +1 -1
- package/runtime/prompts/profiles/requirements-discovery.md +2 -2
- package/runtime/python/okstra_ctl/fix_cycles.py +1 -1
- package/runtime/python/okstra_ctl/implementation_stage.py +46 -39
- package/runtime/python/okstra_ctl/report_views.py +151 -12
- package/runtime/python/okstra_ctl/run.py +24 -24
- package/runtime/python/okstra_ctl/wizard.py +3 -3
- package/runtime/python/okstra_ctl/worktree.py +1 -1
- package/runtime/python/okstra_token_usage/claude.py +58 -19
- package/runtime/python/okstra_token_usage/collect.py +3 -1
- package/runtime/python/okstra_vendor/__init__.py +3 -0
- package/runtime/schemas/final-report-v1.0.schema.json +20 -0
- package/runtime/skills/{okstra-brief → okstra-brief-gen}/SKILL.md +6 -6
- package/runtime/skills/{okstra-brief → okstra-brief-gen}/references/reporter-confirmations.md +1 -1
- package/runtime/skills/{okstra-brief → okstra-brief-gen}/references/tracker-recursion.md +1 -1
- package/runtime/skills/okstra-inspect/SKILL.md +2 -2
- package/runtime/templates/reports/brief.template.md +2 -2
- package/runtime/templates/reports/final-report.template.md +14 -0
- package/runtime/templates/reports/i18n/en.json +23 -12
- package/runtime/templates/reports/i18n/ko.json +23 -12
- package/runtime/templates/reports/report.css +55 -0
- package/runtime/templates/reports/report.js +53 -1
- package/runtime/validators/validate-brief.py +5 -5
- package/runtime/validators/validate-brief.sh +1 -1
- package/src/commands/lifecycle/uninstall.mjs +2 -1
- package/src/lib/skill-catalog.mjs +2 -1
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_approx_clust_coeff.py +0 -41
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_clique.py +0 -112
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_connectivity.py +0 -199
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_density.py +0 -146
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_distance_measures.py +0 -59
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_dominating_set.py +0 -78
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_kcomponents.py +0 -303
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_matching.py +0 -8
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_maxcut.py +0 -94
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_ramsey.py +0 -31
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_steinertree.py +0 -306
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_traveling_salesman.py +0 -1014
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_treewidth.py +0 -274
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_vertex_cover.py +0 -68
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/base_test.py +0 -81
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_connectivity.py +0 -143
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_correlation.py +0 -122
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_mixing.py +0 -174
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_neighbor_degree.py +0 -107
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_pairs.py +0 -87
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_basic.py +0 -125
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_centrality.py +0 -192
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_cluster.py +0 -84
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_covering.py +0 -33
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_edgelist.py +0 -240
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_extendability.py +0 -334
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_generators.py +0 -407
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_link_analysis.py +0 -218
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matching.py +0 -327
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matrix.py +0 -138
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_project.py +0 -409
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_redundancy.py +0 -35
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_spectral_bipartivity.py +0 -80
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality.py +0 -923
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality_subset.py +0 -354
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_closeness_centrality.py +0 -274
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality.py +0 -259
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality_subset.py +0 -147
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_closeness.py +0 -43
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_degree_centrality.py +0 -144
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_dispersion.py +0 -73
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_eigenvector_centrality.py +0 -186
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_group.py +0 -277
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_harmonic_centrality.py +0 -122
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_katz_centrality.py +0 -345
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_laplacian_centrality.py +0 -220
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_load_centrality.py +0 -344
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_percolation_centrality.py +0 -87
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_reaching.py +0 -140
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_second_order_centrality.py +0 -82
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_subgraph.py +0 -110
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_trophic.py +0 -302
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_voterank.py +0 -64
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/test_coloring.py +0 -863
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_asyn_fluid.py +0 -147
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_bipartitions.py +0 -157
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_centrality.py +0 -85
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_divisive.py +0 -106
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_kclique.py +0 -91
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_label_propagation.py +0 -241
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_leiden.py +0 -138
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_local.py +0 -76
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_louvain.py +0 -264
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_lukes.py +0 -152
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_modularity_max.py +0 -340
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_quality.py +0 -139
- package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_utils.py +0 -26
- package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_attracting.py +0 -70
- package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_biconnected.py +0 -248
- package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_connected.py +0 -138
- package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_semiconnected.py +0 -55
- package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_strongly_connected.py +0 -193
- package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_weakly_connected.py +0 -96
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_connectivity.py +0 -421
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_cuts.py +0 -309
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_disjoint_paths.py +0 -249
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_augmentation.py +0 -502
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_kcomponents.py +0 -488
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcomponents.py +0 -323
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcutsets.py +0 -280
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_stoer_wagner.py +0 -102
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gl1.gpickle.bz2 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gw1.gpickle.bz2 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/netgen-2.gpickle.bz2 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_gomory_hu.py +0 -128
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow.py +0 -573
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow_large_graph.py +0 -155
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_mincost.py +0 -475
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_networksimplex.py +0 -481
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/wlm3.gpickle.bz2 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.A99 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.B99 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.A99 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.B99 +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_ismags.py +0 -719
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphism.py +0 -103
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphvf2.py +0 -490
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_match_helpers.py +0 -64
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_temporalisomorphvf2.py +0 -212
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_tree_isomorphism.py +0 -202
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp.py +0 -1655
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp_helpers.py +0 -3118
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2userfunc.py +0 -196
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_hits.py +0 -77
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_pagerank.py +0 -213
- package/runtime/python/okstra_vendor/networkx/algorithms/minors/tests/test_contraction.py +0 -544
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_all.py +0 -328
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_binary.py +0 -451
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_product.py +0 -491
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_unary.py +0 -55
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_astar.py +0 -254
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense.py +0 -212
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense_numpy.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_generic.py +0 -511
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_unweighted.py +0 -149
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_weighted.py +0 -983
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_asteroidal.py +0 -23
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_boundary.py +0 -154
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_bridges.py +0 -144
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_broadcasting.py +0 -109
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chains.py +0 -136
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chordal.py +0 -129
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_clique.py +0 -300
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cluster.py +0 -678
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_communicability.py +0 -80
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_core.py +0 -266
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_covering.py +0 -85
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cuts.py +0 -171
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cycles.py +0 -984
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_d_separation.py +0 -340
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dag.py +0 -835
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_measures.py +0 -831
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_regular.py +0 -85
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominance.py +0 -299
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominating.py +0 -115
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_efficiency.py +0 -58
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_euler.py +0 -314
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graph_hashing.py +0 -872
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graphical.py +0 -163
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hierarchy.py +0 -46
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hybrid.py +0 -24
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_isolate.py +0 -26
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_link_prediction.py +0 -615
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_lowest_common_ancestors.py +0 -459
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_matching.py +0 -556
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_max_weight_clique.py +0 -179
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_mis.py +0 -62
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_moral.py +0 -15
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_node_classification.py +0 -140
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_non_randomness.py +0 -60
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_perfect_graph.py +0 -27
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planar_drawing.py +0 -274
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planarity.py +0 -556
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_polynomials.py +0 -57
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_reciprocity.py +0 -37
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_regular.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_richclub.py +0 -149
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_similarity.py +0 -1158
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_simple_paths.py +0 -803
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smallworld.py +0 -76
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smetric.py +0 -8
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_sparsifiers.py +0 -138
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_structuralholes.py +0 -191
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_summarization.py +0 -642
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_swap.py +0 -179
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_threshold.py +0 -270
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_time_dependent.py +0 -431
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_tournament.py +0 -161
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_triads.py +0 -248
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_vitality.py +0 -41
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_voronoi.py +0 -103
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_walks.py +0 -54
- package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_wiener.py +0 -157
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_beamsearch.py +0 -25
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_bfs.py +0 -203
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_dfs.py +0 -307
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgebfs.py +0 -147
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgedfs.py +0 -131
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_branchings.py +0 -624
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_coding.py +0 -114
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_decomposition.py +0 -79
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_distance_measures.py +0 -99
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_mst.py +0 -934
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_operations.py +0 -53
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_recognition.py +0 -174
- package/runtime/python/okstra_vendor/networkx/classes/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/classes/tests/dispatch_interface.py +0 -192
- package/runtime/python/okstra_vendor/networkx/classes/tests/historical_tests.py +0 -476
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_coreviews.py +0 -362
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph.py +0 -331
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph_historical.py +0 -110
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_filters.py +0 -177
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_function.py +0 -1045
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph.py +0 -950
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph_historical.py +0 -12
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_graphviews.py +0 -349
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_multidigraph.py +0 -459
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_multigraph.py +0 -528
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_reportviews.py +0 -1421
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_special.py +0 -131
- package/runtime/python/okstra_vendor/networkx/classes/tests/test_subgraphviews.py +0 -371
- package/runtime/python/okstra_vendor/networkx/conftest.py +0 -261
- package/runtime/python/okstra_vendor/networkx/drawing/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_complex.png +0 -0
- package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_empty_graph.png +0 -0
- package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_house_with_colors.png +0 -0
- package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_labels_and_colors.png +0 -0
- package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_shortest_path.png +0 -0
- package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_house_with_colors.png +0 -0
- package/runtime/python/okstra_vendor/networkx/drawing/tests/test_agraph.py +0 -237
- package/runtime/python/okstra_vendor/networkx/drawing/tests/test_image_comparison_pylab_mpl.py +0 -229
- package/runtime/python/okstra_vendor/networkx/drawing/tests/test_latex.py +0 -285
- package/runtime/python/okstra_vendor/networkx/drawing/tests/test_layout.py +0 -631
- package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pydot.py +0 -146
- package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pylab.py +0 -1582
- package/runtime/python/okstra_vendor/networkx/generators/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_atlas.py +0 -75
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_classic.py +0 -642
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_cographs.py +0 -20
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_community.py +0 -362
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_degree_seq.py +0 -224
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_directed.py +0 -189
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_duplication.py +0 -103
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_ego.py +0 -39
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_expanders.py +0 -182
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_geometric.py +0 -488
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_harary_graph.py +0 -133
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_internet_as_graphs.py +0 -221
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_intersection.py +0 -28
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_interval_graph.py +0 -144
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_joint_degree_seq.py +0 -125
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_lattice.py +0 -264
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_line.py +0 -316
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_mycielski.py +0 -30
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_nonisomorphic_trees.py +0 -82
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_clustered.py +0 -33
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_graphs.py +0 -495
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_small.py +0 -220
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_spectral_graph_forge.py +0 -49
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_stochastic.py +0 -72
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_sudoku.py +0 -92
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_time_series.py +0 -64
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_trees.py +0 -195
- package/runtime/python/okstra_vendor/networkx/generators/tests/test_triads.py +0 -15
- package/runtime/python/okstra_vendor/networkx/linalg/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/linalg/tests/test_algebraic_connectivity.py +0 -400
- package/runtime/python/okstra_vendor/networkx/linalg/tests/test_attrmatrix.py +0 -108
- package/runtime/python/okstra_vendor/networkx/linalg/tests/test_bethehessian.py +0 -40
- package/runtime/python/okstra_vendor/networkx/linalg/tests/test_graphmatrix.py +0 -275
- package/runtime/python/okstra_vendor/networkx/linalg/tests/test_laplacian.py +0 -334
- package/runtime/python/okstra_vendor/networkx/linalg/tests/test_modularity.py +0 -86
- package/runtime/python/okstra_vendor/networkx/linalg/tests/test_spectrum.py +0 -70
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_adjacency.py +0 -78
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_cytoscape.py +0 -78
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_node_link.py +0 -109
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_tree.py +0 -48
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_adjlist.py +0 -354
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_edgelist.py +0 -318
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gexf.py +0 -612
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gml.py +0 -744
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graph6.py +0 -181
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graphml.py +0 -1531
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_leda.py +0 -30
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_p2g.py +0 -63
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_pajek.py +0 -128
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_sparse6.py +0 -166
- package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_text.py +0 -1742
- package/runtime/python/okstra_vendor/networkx/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/tests/test_all_random_functions.py +0 -248
- package/runtime/python/okstra_vendor/networkx/tests/test_convert.py +0 -321
- package/runtime/python/okstra_vendor/networkx/tests/test_convert_numpy.py +0 -531
- package/runtime/python/okstra_vendor/networkx/tests/test_convert_pandas.py +0 -349
- package/runtime/python/okstra_vendor/networkx/tests/test_convert_scipy.py +0 -281
- package/runtime/python/okstra_vendor/networkx/tests/test_exceptions.py +0 -40
- package/runtime/python/okstra_vendor/networkx/tests/test_import.py +0 -11
- package/runtime/python/okstra_vendor/networkx/tests/test_lazy_imports.py +0 -96
- package/runtime/python/okstra_vendor/networkx/tests/test_relabel.py +0 -349
- package/runtime/python/okstra_vendor/networkx/tests/test_removed_functions_exception_messages.py +0 -8
- package/runtime/python/okstra_vendor/networkx/utils/tests/__init__.py +0 -0
- package/runtime/python/okstra_vendor/networkx/utils/tests/test__init.py +0 -11
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_backends.py +0 -225
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_config.py +0 -263
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_decorators.py +0 -510
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_heaps.py +0 -131
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_mapped_queue.py +0 -268
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_misc.py +0 -393
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_random_sequence.py +0 -53
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_rcm.py +0 -63
- package/runtime/python/okstra_vendor/networkx/utils/tests/test_unionfind.py +0 -55
|
@@ -1,556 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
from networkx.algorithms.planarity import (
|
|
5
|
-
check_planarity_recursive,
|
|
6
|
-
get_counterexample,
|
|
7
|
-
get_counterexample_recursive,
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class TestLRPlanarity:
|
|
12
|
-
"""Nose Unit tests for the :mod:`networkx.algorithms.planarity` module.
|
|
13
|
-
|
|
14
|
-
Tests three things:
|
|
15
|
-
1. Check that the result is correct
|
|
16
|
-
(returns planar if and only if the graph is actually planar)
|
|
17
|
-
2. In case a counter example is returned: Check if it is correct
|
|
18
|
-
3. In case an embedding is returned: Check if its actually an embedding
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
@staticmethod
|
|
22
|
-
def check_graph(G, is_planar=None):
|
|
23
|
-
"""Raises an exception if the lr_planarity check returns a wrong result
|
|
24
|
-
|
|
25
|
-
Parameters
|
|
26
|
-
----------
|
|
27
|
-
G : NetworkX graph
|
|
28
|
-
is_planar : bool
|
|
29
|
-
The expected result of the planarity check.
|
|
30
|
-
If set to None only counter example or embedding are verified.
|
|
31
|
-
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
# obtain results of planarity check
|
|
35
|
-
is_planar_lr, result = nx.check_planarity(G, True)
|
|
36
|
-
is_planar_lr_rec, result_rec = check_planarity_recursive(G, True)
|
|
37
|
-
|
|
38
|
-
if is_planar is not None:
|
|
39
|
-
# set a message for the assert
|
|
40
|
-
if is_planar:
|
|
41
|
-
msg = "Wrong planarity check result. Should be planar."
|
|
42
|
-
else:
|
|
43
|
-
msg = "Wrong planarity check result. Should be non-planar."
|
|
44
|
-
|
|
45
|
-
# check if the result is as expected
|
|
46
|
-
assert is_planar == is_planar_lr, msg
|
|
47
|
-
assert is_planar == is_planar_lr_rec, msg
|
|
48
|
-
|
|
49
|
-
if is_planar_lr:
|
|
50
|
-
# check embedding
|
|
51
|
-
check_embedding(G, result)
|
|
52
|
-
check_embedding(G, result_rec)
|
|
53
|
-
else:
|
|
54
|
-
# check counter example
|
|
55
|
-
check_counterexample(G, result)
|
|
56
|
-
check_counterexample(G, result_rec)
|
|
57
|
-
|
|
58
|
-
def test_simple_planar_graph(self):
|
|
59
|
-
e = [
|
|
60
|
-
(1, 2),
|
|
61
|
-
(2, 3),
|
|
62
|
-
(3, 4),
|
|
63
|
-
(4, 6),
|
|
64
|
-
(6, 7),
|
|
65
|
-
(7, 1),
|
|
66
|
-
(1, 5),
|
|
67
|
-
(5, 2),
|
|
68
|
-
(2, 4),
|
|
69
|
-
(4, 5),
|
|
70
|
-
(5, 7),
|
|
71
|
-
]
|
|
72
|
-
self.check_graph(nx.Graph(e), is_planar=True)
|
|
73
|
-
|
|
74
|
-
def test_planar_with_selfloop(self):
|
|
75
|
-
e = [
|
|
76
|
-
(1, 1),
|
|
77
|
-
(2, 2),
|
|
78
|
-
(3, 3),
|
|
79
|
-
(4, 4),
|
|
80
|
-
(5, 5),
|
|
81
|
-
(1, 2),
|
|
82
|
-
(1, 3),
|
|
83
|
-
(1, 5),
|
|
84
|
-
(2, 5),
|
|
85
|
-
(2, 4),
|
|
86
|
-
(3, 4),
|
|
87
|
-
(3, 5),
|
|
88
|
-
(4, 5),
|
|
89
|
-
]
|
|
90
|
-
self.check_graph(nx.Graph(e), is_planar=True)
|
|
91
|
-
|
|
92
|
-
def test_k3_3(self):
|
|
93
|
-
self.check_graph(nx.complete_bipartite_graph(3, 3), is_planar=False)
|
|
94
|
-
|
|
95
|
-
def test_k5(self):
|
|
96
|
-
self.check_graph(nx.complete_graph(5), is_planar=False)
|
|
97
|
-
|
|
98
|
-
def test_multiple_components_planar(self):
|
|
99
|
-
e = [(1, 2), (2, 3), (3, 1), (4, 5), (5, 6), (6, 4)]
|
|
100
|
-
self.check_graph(nx.Graph(e), is_planar=True)
|
|
101
|
-
|
|
102
|
-
def test_multiple_components_non_planar(self):
|
|
103
|
-
G = nx.complete_graph(5)
|
|
104
|
-
# add another planar component to the non planar component
|
|
105
|
-
# G stays non planar
|
|
106
|
-
G.add_edges_from([(6, 7), (7, 8), (8, 6)])
|
|
107
|
-
self.check_graph(G, is_planar=False)
|
|
108
|
-
|
|
109
|
-
def test_non_planar_with_selfloop(self):
|
|
110
|
-
G = nx.complete_graph(5)
|
|
111
|
-
# add self loops
|
|
112
|
-
for i in range(5):
|
|
113
|
-
G.add_edge(i, i)
|
|
114
|
-
self.check_graph(G, is_planar=False)
|
|
115
|
-
|
|
116
|
-
def test_non_planar1(self):
|
|
117
|
-
# tests a graph that has no subgraph directly isomorph to K5 or K3_3
|
|
118
|
-
e = [
|
|
119
|
-
(1, 5),
|
|
120
|
-
(1, 6),
|
|
121
|
-
(1, 7),
|
|
122
|
-
(2, 6),
|
|
123
|
-
(2, 3),
|
|
124
|
-
(3, 5),
|
|
125
|
-
(3, 7),
|
|
126
|
-
(4, 5),
|
|
127
|
-
(4, 6),
|
|
128
|
-
(4, 7),
|
|
129
|
-
]
|
|
130
|
-
self.check_graph(nx.Graph(e), is_planar=False)
|
|
131
|
-
|
|
132
|
-
def test_loop(self):
|
|
133
|
-
# test a graph with a selfloop
|
|
134
|
-
e = [(1, 2), (2, 2)]
|
|
135
|
-
G = nx.Graph(e)
|
|
136
|
-
self.check_graph(G, is_planar=True)
|
|
137
|
-
|
|
138
|
-
def test_comp(self):
|
|
139
|
-
# test multiple component graph
|
|
140
|
-
e = [(1, 2), (3, 4)]
|
|
141
|
-
G = nx.Graph(e)
|
|
142
|
-
G.remove_edge(1, 2)
|
|
143
|
-
self.check_graph(G, is_planar=True)
|
|
144
|
-
|
|
145
|
-
def test_goldner_harary(self):
|
|
146
|
-
# test goldner-harary graph (a maximal planar graph)
|
|
147
|
-
e = [
|
|
148
|
-
(1, 2),
|
|
149
|
-
(1, 3),
|
|
150
|
-
(1, 4),
|
|
151
|
-
(1, 5),
|
|
152
|
-
(1, 7),
|
|
153
|
-
(1, 8),
|
|
154
|
-
(1, 10),
|
|
155
|
-
(1, 11),
|
|
156
|
-
(2, 3),
|
|
157
|
-
(2, 4),
|
|
158
|
-
(2, 6),
|
|
159
|
-
(2, 7),
|
|
160
|
-
(2, 9),
|
|
161
|
-
(2, 10),
|
|
162
|
-
(2, 11),
|
|
163
|
-
(3, 4),
|
|
164
|
-
(4, 5),
|
|
165
|
-
(4, 6),
|
|
166
|
-
(4, 7),
|
|
167
|
-
(5, 7),
|
|
168
|
-
(6, 7),
|
|
169
|
-
(7, 8),
|
|
170
|
-
(7, 9),
|
|
171
|
-
(7, 10),
|
|
172
|
-
(8, 10),
|
|
173
|
-
(9, 10),
|
|
174
|
-
(10, 11),
|
|
175
|
-
]
|
|
176
|
-
G = nx.Graph(e)
|
|
177
|
-
self.check_graph(G, is_planar=True)
|
|
178
|
-
|
|
179
|
-
def test_planar_multigraph(self):
|
|
180
|
-
G = nx.MultiGraph([(1, 2), (1, 2), (1, 2), (1, 2), (2, 3), (3, 1)])
|
|
181
|
-
self.check_graph(G, is_planar=True)
|
|
182
|
-
|
|
183
|
-
def test_non_planar_multigraph(self):
|
|
184
|
-
G = nx.MultiGraph(nx.complete_graph(5))
|
|
185
|
-
G.add_edges_from([(1, 2)] * 5)
|
|
186
|
-
self.check_graph(G, is_planar=False)
|
|
187
|
-
|
|
188
|
-
def test_planar_digraph(self):
|
|
189
|
-
G = nx.DiGraph([(1, 2), (2, 3), (2, 4), (4, 1), (4, 2), (1, 4), (3, 2)])
|
|
190
|
-
self.check_graph(G, is_planar=True)
|
|
191
|
-
|
|
192
|
-
def test_non_planar_digraph(self):
|
|
193
|
-
G = nx.DiGraph(nx.complete_graph(5))
|
|
194
|
-
G.remove_edge(1, 2)
|
|
195
|
-
G.remove_edge(4, 1)
|
|
196
|
-
self.check_graph(G, is_planar=False)
|
|
197
|
-
|
|
198
|
-
def test_single_component(self):
|
|
199
|
-
# Test a graph with only a single node
|
|
200
|
-
G = nx.Graph()
|
|
201
|
-
G.add_node(1)
|
|
202
|
-
self.check_graph(G, is_planar=True)
|
|
203
|
-
|
|
204
|
-
def test_graph1(self):
|
|
205
|
-
G = nx.Graph(
|
|
206
|
-
[
|
|
207
|
-
(3, 10),
|
|
208
|
-
(2, 13),
|
|
209
|
-
(1, 13),
|
|
210
|
-
(7, 11),
|
|
211
|
-
(0, 8),
|
|
212
|
-
(8, 13),
|
|
213
|
-
(0, 2),
|
|
214
|
-
(0, 7),
|
|
215
|
-
(0, 10),
|
|
216
|
-
(1, 7),
|
|
217
|
-
]
|
|
218
|
-
)
|
|
219
|
-
self.check_graph(G, is_planar=True)
|
|
220
|
-
|
|
221
|
-
def test_graph2(self):
|
|
222
|
-
G = nx.Graph(
|
|
223
|
-
[
|
|
224
|
-
(1, 2),
|
|
225
|
-
(4, 13),
|
|
226
|
-
(0, 13),
|
|
227
|
-
(4, 5),
|
|
228
|
-
(7, 10),
|
|
229
|
-
(1, 7),
|
|
230
|
-
(0, 3),
|
|
231
|
-
(2, 6),
|
|
232
|
-
(5, 6),
|
|
233
|
-
(7, 13),
|
|
234
|
-
(4, 8),
|
|
235
|
-
(0, 8),
|
|
236
|
-
(0, 9),
|
|
237
|
-
(2, 13),
|
|
238
|
-
(6, 7),
|
|
239
|
-
(3, 6),
|
|
240
|
-
(2, 8),
|
|
241
|
-
]
|
|
242
|
-
)
|
|
243
|
-
self.check_graph(G, is_planar=False)
|
|
244
|
-
|
|
245
|
-
def test_graph3(self):
|
|
246
|
-
G = nx.Graph(
|
|
247
|
-
[
|
|
248
|
-
(0, 7),
|
|
249
|
-
(3, 11),
|
|
250
|
-
(3, 4),
|
|
251
|
-
(8, 9),
|
|
252
|
-
(4, 11),
|
|
253
|
-
(1, 7),
|
|
254
|
-
(1, 13),
|
|
255
|
-
(1, 11),
|
|
256
|
-
(3, 5),
|
|
257
|
-
(5, 7),
|
|
258
|
-
(1, 3),
|
|
259
|
-
(0, 4),
|
|
260
|
-
(5, 11),
|
|
261
|
-
(5, 13),
|
|
262
|
-
]
|
|
263
|
-
)
|
|
264
|
-
self.check_graph(G, is_planar=False)
|
|
265
|
-
|
|
266
|
-
def test_counterexample_planar(self):
|
|
267
|
-
with pytest.raises(nx.NetworkXException):
|
|
268
|
-
# Try to get a counterexample of a planar graph
|
|
269
|
-
G = nx.Graph()
|
|
270
|
-
G.add_node(1)
|
|
271
|
-
get_counterexample(G)
|
|
272
|
-
|
|
273
|
-
def test_counterexample_planar_recursive(self):
|
|
274
|
-
with pytest.raises(nx.NetworkXException):
|
|
275
|
-
# Try to get a counterexample of a planar graph
|
|
276
|
-
G = nx.Graph()
|
|
277
|
-
G.add_node(1)
|
|
278
|
-
get_counterexample_recursive(G)
|
|
279
|
-
|
|
280
|
-
def test_edge_removal_from_planar_embedding(self):
|
|
281
|
-
# PlanarEmbedding.check_structure() must succeed after edge removal
|
|
282
|
-
edges = ((0, 1), (1, 2), (2, 3), (3, 4), (4, 0), (0, 2), (0, 3))
|
|
283
|
-
G = nx.Graph(edges)
|
|
284
|
-
cert, P = nx.check_planarity(G)
|
|
285
|
-
assert cert is True
|
|
286
|
-
P.remove_edge(0, 2)
|
|
287
|
-
self.check_graph(P, is_planar=True)
|
|
288
|
-
P.add_half_edge_ccw(1, 3, 2)
|
|
289
|
-
P.add_half_edge_cw(3, 1, 2)
|
|
290
|
-
self.check_graph(P, is_planar=True)
|
|
291
|
-
P.remove_edges_from(((0, 3), (1, 3)))
|
|
292
|
-
self.check_graph(P, is_planar=True)
|
|
293
|
-
|
|
294
|
-
@pytest.mark.parametrize("graph_type", (nx.Graph, nx.MultiGraph))
|
|
295
|
-
def test_graph_planar_embedding_to_undirected(self, graph_type):
|
|
296
|
-
G = graph_type([(0, 1), (0, 1), (1, 2), (2, 3), (3, 0), (0, 2)])
|
|
297
|
-
is_planar, P = nx.check_planarity(G)
|
|
298
|
-
assert is_planar
|
|
299
|
-
U = P.to_undirected()
|
|
300
|
-
assert isinstance(U, nx.Graph)
|
|
301
|
-
assert all((d == {} for _, _, d in U.edges(data=True)))
|
|
302
|
-
|
|
303
|
-
@pytest.mark.parametrize(
|
|
304
|
-
"reciprocal, as_view", [(True, True), (True, False), (False, True)]
|
|
305
|
-
)
|
|
306
|
-
def test_planar_embedding_to_undirected_invalid_parameters(
|
|
307
|
-
self, reciprocal, as_view
|
|
308
|
-
):
|
|
309
|
-
G = nx.Graph([(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)])
|
|
310
|
-
is_planar, P = nx.check_planarity(G)
|
|
311
|
-
assert is_planar
|
|
312
|
-
with pytest.raises(ValueError, match="is not supported for PlanarEmbedding."):
|
|
313
|
-
P.to_undirected(reciprocal=reciprocal, as_view=as_view)
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
def check_embedding(G, embedding):
|
|
317
|
-
"""Raises an exception if the combinatorial embedding is not correct
|
|
318
|
-
|
|
319
|
-
Parameters
|
|
320
|
-
----------
|
|
321
|
-
G : NetworkX graph
|
|
322
|
-
embedding : a dict mapping nodes to a list of edges
|
|
323
|
-
This specifies the ordering of the outgoing edges from a node for
|
|
324
|
-
a combinatorial embedding
|
|
325
|
-
|
|
326
|
-
Notes
|
|
327
|
-
-----
|
|
328
|
-
Checks the following things:
|
|
329
|
-
- The type of the embedding is correct
|
|
330
|
-
- The nodes and edges match the original graph
|
|
331
|
-
- Every half edge has its matching opposite half edge
|
|
332
|
-
- No intersections of edges (checked by Euler's formula)
|
|
333
|
-
"""
|
|
334
|
-
|
|
335
|
-
if not isinstance(embedding, nx.PlanarEmbedding):
|
|
336
|
-
raise nx.NetworkXException("Bad embedding. Not of type nx.PlanarEmbedding")
|
|
337
|
-
|
|
338
|
-
# Check structure
|
|
339
|
-
embedding.check_structure()
|
|
340
|
-
|
|
341
|
-
# Check that graphs are equivalent
|
|
342
|
-
|
|
343
|
-
assert set(G.nodes) == set(embedding.nodes), (
|
|
344
|
-
"Bad embedding. Nodes don't match the original graph."
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
# Check that the edges are equal
|
|
348
|
-
g_edges = set()
|
|
349
|
-
for edge in G.edges:
|
|
350
|
-
if edge[0] != edge[1]:
|
|
351
|
-
g_edges.add((edge[0], edge[1]))
|
|
352
|
-
g_edges.add((edge[1], edge[0]))
|
|
353
|
-
assert g_edges == set(embedding.edges), (
|
|
354
|
-
"Bad embedding. Edges don't match the original graph."
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
def check_counterexample(G, sub_graph):
|
|
359
|
-
"""Raises an exception if the counterexample is wrong.
|
|
360
|
-
|
|
361
|
-
Parameters
|
|
362
|
-
----------
|
|
363
|
-
G : NetworkX graph
|
|
364
|
-
subdivision_nodes : set
|
|
365
|
-
A set of nodes inducing a subgraph as a counterexample
|
|
366
|
-
"""
|
|
367
|
-
# 1. Create the sub graph
|
|
368
|
-
sub_graph = nx.Graph(sub_graph)
|
|
369
|
-
|
|
370
|
-
# 2. Remove self loops
|
|
371
|
-
for u in sub_graph:
|
|
372
|
-
if sub_graph.has_edge(u, u):
|
|
373
|
-
sub_graph.remove_edge(u, u)
|
|
374
|
-
|
|
375
|
-
# keep track of nodes we might need to contract
|
|
376
|
-
contract = list(sub_graph)
|
|
377
|
-
|
|
378
|
-
# 3. Contract Edges
|
|
379
|
-
while len(contract) > 0:
|
|
380
|
-
contract_node = contract.pop()
|
|
381
|
-
if contract_node not in sub_graph:
|
|
382
|
-
# Node was already contracted
|
|
383
|
-
continue
|
|
384
|
-
degree = sub_graph.degree[contract_node]
|
|
385
|
-
# Check if we can remove the node
|
|
386
|
-
if degree == 2:
|
|
387
|
-
# Get the two neighbors
|
|
388
|
-
neighbors = iter(sub_graph[contract_node])
|
|
389
|
-
u = next(neighbors)
|
|
390
|
-
v = next(neighbors)
|
|
391
|
-
# Save nodes for later
|
|
392
|
-
contract.append(u)
|
|
393
|
-
contract.append(v)
|
|
394
|
-
# Contract edge
|
|
395
|
-
sub_graph.remove_node(contract_node)
|
|
396
|
-
sub_graph.add_edge(u, v)
|
|
397
|
-
|
|
398
|
-
# 4. Check for isomorphism with K5 or K3_3 graphs
|
|
399
|
-
if len(sub_graph) == 5:
|
|
400
|
-
if not nx.is_isomorphic(nx.complete_graph(5), sub_graph):
|
|
401
|
-
raise nx.NetworkXException("Bad counter example.")
|
|
402
|
-
elif len(sub_graph) == 6:
|
|
403
|
-
if not nx.is_isomorphic(nx.complete_bipartite_graph(3, 3), sub_graph):
|
|
404
|
-
raise nx.NetworkXException("Bad counter example.")
|
|
405
|
-
else:
|
|
406
|
-
raise nx.NetworkXException("Bad counter example.")
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
class TestPlanarEmbeddingClass:
|
|
410
|
-
def test_add_half_edge(self):
|
|
411
|
-
embedding = nx.PlanarEmbedding()
|
|
412
|
-
embedding.add_half_edge(0, 1)
|
|
413
|
-
with pytest.raises(
|
|
414
|
-
nx.NetworkXException, match="Invalid clockwise reference node."
|
|
415
|
-
):
|
|
416
|
-
embedding.add_half_edge(0, 2, cw=3)
|
|
417
|
-
with pytest.raises(
|
|
418
|
-
nx.NetworkXException, match="Invalid counterclockwise reference node."
|
|
419
|
-
):
|
|
420
|
-
embedding.add_half_edge(0, 2, ccw=3)
|
|
421
|
-
with pytest.raises(
|
|
422
|
-
nx.NetworkXException, match="Only one of cw/ccw can be specified."
|
|
423
|
-
):
|
|
424
|
-
embedding.add_half_edge(0, 2, cw=1, ccw=1)
|
|
425
|
-
with pytest.raises(
|
|
426
|
-
nx.NetworkXException,
|
|
427
|
-
match=(
|
|
428
|
-
r"Node already has out-half-edge\(s\), either"
|
|
429
|
-
" cw or ccw reference node required."
|
|
430
|
-
),
|
|
431
|
-
):
|
|
432
|
-
embedding.add_half_edge(0, 2)
|
|
433
|
-
# these should work
|
|
434
|
-
embedding.add_half_edge(0, 2, cw=1)
|
|
435
|
-
embedding.add_half_edge(0, 3, ccw=1)
|
|
436
|
-
assert sorted(embedding.edges(data=True)) == [
|
|
437
|
-
(0, 1, {"ccw": 2, "cw": 3}),
|
|
438
|
-
(0, 2, {"cw": 1, "ccw": 3}),
|
|
439
|
-
(0, 3, {"cw": 2, "ccw": 1}),
|
|
440
|
-
]
|
|
441
|
-
|
|
442
|
-
def test_get_data(self):
|
|
443
|
-
embedding = self.get_star_embedding(4)
|
|
444
|
-
data = embedding.get_data()
|
|
445
|
-
data_cmp = {0: [3, 2, 1], 1: [0], 2: [0], 3: [0]}
|
|
446
|
-
assert data == data_cmp
|
|
447
|
-
|
|
448
|
-
def test_edge_removal(self):
|
|
449
|
-
embedding = nx.PlanarEmbedding()
|
|
450
|
-
embedding.set_data(
|
|
451
|
-
{
|
|
452
|
-
1: [2, 5, 7],
|
|
453
|
-
2: [1, 3, 4, 5],
|
|
454
|
-
3: [2, 4],
|
|
455
|
-
4: [3, 6, 5, 2],
|
|
456
|
-
5: [7, 1, 2, 4],
|
|
457
|
-
6: [4, 7],
|
|
458
|
-
7: [6, 1, 5],
|
|
459
|
-
}
|
|
460
|
-
)
|
|
461
|
-
# remove_edges_from() calls remove_edge(), so both are tested here
|
|
462
|
-
embedding.remove_edges_from(((5, 4), (1, 5)))
|
|
463
|
-
embedding.check_structure()
|
|
464
|
-
embedding_expected = nx.PlanarEmbedding()
|
|
465
|
-
embedding_expected.set_data(
|
|
466
|
-
{
|
|
467
|
-
1: [2, 7],
|
|
468
|
-
2: [1, 3, 4, 5],
|
|
469
|
-
3: [2, 4],
|
|
470
|
-
4: [3, 6, 2],
|
|
471
|
-
5: [7, 2],
|
|
472
|
-
6: [4, 7],
|
|
473
|
-
7: [6, 1, 5],
|
|
474
|
-
}
|
|
475
|
-
)
|
|
476
|
-
assert nx.utils.graphs_equal(embedding, embedding_expected)
|
|
477
|
-
|
|
478
|
-
def test_missing_edge_orientation(self):
|
|
479
|
-
embedding = nx.PlanarEmbedding({1: {2: {}}, 2: {1: {}}})
|
|
480
|
-
with pytest.raises(nx.NetworkXException):
|
|
481
|
-
# Invalid structure because the orientation of the edge was not set
|
|
482
|
-
embedding.check_structure()
|
|
483
|
-
|
|
484
|
-
def test_invalid_edge_orientation(self):
|
|
485
|
-
embedding = nx.PlanarEmbedding(
|
|
486
|
-
{
|
|
487
|
-
1: {2: {"cw": 2, "ccw": 2}},
|
|
488
|
-
2: {1: {"cw": 1, "ccw": 1}},
|
|
489
|
-
1: {3: {}},
|
|
490
|
-
3: {1: {}},
|
|
491
|
-
}
|
|
492
|
-
)
|
|
493
|
-
with pytest.raises(nx.NetworkXException):
|
|
494
|
-
embedding.check_structure()
|
|
495
|
-
|
|
496
|
-
def test_missing_half_edge(self):
|
|
497
|
-
embedding = nx.PlanarEmbedding()
|
|
498
|
-
embedding.add_half_edge(1, 2)
|
|
499
|
-
with pytest.raises(nx.NetworkXException):
|
|
500
|
-
# Invalid structure because other half edge is missing
|
|
501
|
-
embedding.check_structure()
|
|
502
|
-
|
|
503
|
-
def test_not_fulfilling_euler_formula(self):
|
|
504
|
-
embedding = nx.PlanarEmbedding()
|
|
505
|
-
for i in range(5):
|
|
506
|
-
ref = None
|
|
507
|
-
for j in range(5):
|
|
508
|
-
if i != j:
|
|
509
|
-
embedding.add_half_edge(i, j, cw=ref)
|
|
510
|
-
ref = j
|
|
511
|
-
with pytest.raises(nx.NetworkXException):
|
|
512
|
-
embedding.check_structure()
|
|
513
|
-
|
|
514
|
-
def test_missing_reference(self):
|
|
515
|
-
embedding = nx.PlanarEmbedding()
|
|
516
|
-
with pytest.raises(nx.NetworkXException, match="Invalid reference node."):
|
|
517
|
-
embedding.add_half_edge(1, 2, ccw=3)
|
|
518
|
-
|
|
519
|
-
def test_connect_components(self):
|
|
520
|
-
embedding = nx.PlanarEmbedding()
|
|
521
|
-
embedding.connect_components(1, 2)
|
|
522
|
-
|
|
523
|
-
def test_successful_face_traversal(self):
|
|
524
|
-
embedding = nx.PlanarEmbedding()
|
|
525
|
-
embedding.add_half_edge(1, 2)
|
|
526
|
-
embedding.add_half_edge(2, 1)
|
|
527
|
-
face = embedding.traverse_face(1, 2)
|
|
528
|
-
assert face == [1, 2]
|
|
529
|
-
|
|
530
|
-
def test_unsuccessful_face_traversal(self):
|
|
531
|
-
embedding = nx.PlanarEmbedding(
|
|
532
|
-
{1: {2: {"cw": 3, "ccw": 2}}, 2: {1: {"cw": 3, "ccw": 1}}}
|
|
533
|
-
)
|
|
534
|
-
with pytest.raises(nx.NetworkXException):
|
|
535
|
-
embedding.traverse_face(1, 2)
|
|
536
|
-
|
|
537
|
-
def test_forbidden_methods(self):
|
|
538
|
-
embedding = nx.PlanarEmbedding()
|
|
539
|
-
embedding.add_node(42) # no exception
|
|
540
|
-
embedding.add_nodes_from([(23, 24)]) # no exception
|
|
541
|
-
with pytest.raises(NotImplementedError):
|
|
542
|
-
embedding.add_edge(1, 3)
|
|
543
|
-
with pytest.raises(NotImplementedError):
|
|
544
|
-
embedding.add_edges_from([(0, 2), (1, 4)])
|
|
545
|
-
with pytest.raises(NotImplementedError):
|
|
546
|
-
embedding.add_weighted_edges_from([(0, 2, 350), (1, 4, 125)])
|
|
547
|
-
|
|
548
|
-
@staticmethod
|
|
549
|
-
def get_star_embedding(n):
|
|
550
|
-
embedding = nx.PlanarEmbedding()
|
|
551
|
-
ref = None
|
|
552
|
-
for i in range(1, n):
|
|
553
|
-
embedding.add_half_edge(0, i, cw=ref)
|
|
554
|
-
ref = i
|
|
555
|
-
embedding.add_half_edge(i, 0)
|
|
556
|
-
return embedding
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"""Unit tests for the :mod:`networkx.algorithms.polynomials` module."""
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
import networkx as nx
|
|
6
|
-
|
|
7
|
-
sympy = pytest.importorskip("sympy")
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# Mapping of input graphs to a string representation of their tutte polynomials
|
|
11
|
-
_test_tutte_graphs = {
|
|
12
|
-
nx.complete_graph(1): "1",
|
|
13
|
-
nx.complete_graph(4): "x**3 + 3*x**2 + 4*x*y + 2*x + y**3 + 3*y**2 + 2*y",
|
|
14
|
-
nx.cycle_graph(5): "x**4 + x**3 + x**2 + x + y",
|
|
15
|
-
nx.diamond_graph(): "x**3 + 2*x**2 + 2*x*y + x + y**2 + y",
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
_test_chromatic_graphs = {
|
|
19
|
-
nx.complete_graph(1): "x",
|
|
20
|
-
nx.complete_graph(4): "x**4 - 6*x**3 + 11*x**2 - 6*x",
|
|
21
|
-
nx.cycle_graph(5): "x**5 - 5*x**4 + 10*x**3 - 10*x**2 + 4*x",
|
|
22
|
-
nx.diamond_graph(): "x**4 - 5*x**3 + 8*x**2 - 4*x",
|
|
23
|
-
nx.path_graph(5): "x**5 - 4*x**4 + 6*x**3 - 4*x**2 + x",
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@pytest.mark.parametrize(("G", "expected"), _test_tutte_graphs.items())
|
|
28
|
-
def test_tutte_polynomial(G, expected):
|
|
29
|
-
assert nx.tutte_polynomial(G).equals(expected)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@pytest.mark.parametrize("G", _test_tutte_graphs.keys())
|
|
33
|
-
def test_tutte_polynomial_disjoint(G):
|
|
34
|
-
"""Tutte polynomial factors into the Tutte polynomials of its components.
|
|
35
|
-
Verify this property with the disjoint union of two copies of the input graph.
|
|
36
|
-
"""
|
|
37
|
-
t_g = nx.tutte_polynomial(G)
|
|
38
|
-
H = nx.disjoint_union(G, G)
|
|
39
|
-
t_h = nx.tutte_polynomial(H)
|
|
40
|
-
assert sympy.simplify(t_g * t_g).equals(t_h)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@pytest.mark.parametrize(("G", "expected"), _test_chromatic_graphs.items())
|
|
44
|
-
def test_chromatic_polynomial(G, expected):
|
|
45
|
-
assert nx.chromatic_polynomial(G).equals(expected)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@pytest.mark.parametrize("G", _test_chromatic_graphs.keys())
|
|
49
|
-
def test_chromatic_polynomial_disjoint(G):
|
|
50
|
-
"""Chromatic polynomial factors into the Chromatic polynomials of its
|
|
51
|
-
components. Verify this property with the disjoint union of two copies of
|
|
52
|
-
the input graph.
|
|
53
|
-
"""
|
|
54
|
-
x_g = nx.chromatic_polynomial(G)
|
|
55
|
-
H = nx.disjoint_union(G, G)
|
|
56
|
-
x_h = nx.chromatic_polynomial(H)
|
|
57
|
-
assert sympy.simplify(x_g * x_g).equals(x_h)
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class TestReciprocity:
|
|
7
|
-
# test overall reciprocity by passing whole graph
|
|
8
|
-
def test_reciprocity_digraph(self):
|
|
9
|
-
DG = nx.DiGraph([(1, 2), (2, 1)])
|
|
10
|
-
reciprocity = nx.reciprocity(DG)
|
|
11
|
-
assert reciprocity == 1.0
|
|
12
|
-
|
|
13
|
-
# test empty graph's overall reciprocity which will throw an error
|
|
14
|
-
def test_overall_reciprocity_empty_graph(self):
|
|
15
|
-
with pytest.raises(nx.NetworkXError):
|
|
16
|
-
DG = nx.DiGraph()
|
|
17
|
-
nx.overall_reciprocity(DG)
|
|
18
|
-
|
|
19
|
-
# test for reciprocity for a list of nodes
|
|
20
|
-
def test_reciprocity_graph_nodes(self):
|
|
21
|
-
DG = nx.DiGraph([(1, 2), (2, 3), (3, 2)])
|
|
22
|
-
reciprocity = nx.reciprocity(DG, [1, 2])
|
|
23
|
-
expected_reciprocity = {1: 0.0, 2: 0.6666666666666666}
|
|
24
|
-
assert reciprocity == expected_reciprocity
|
|
25
|
-
|
|
26
|
-
# test for reciprocity for a single node
|
|
27
|
-
def test_reciprocity_graph_node(self):
|
|
28
|
-
DG = nx.DiGraph([(1, 2), (2, 3), (3, 2)])
|
|
29
|
-
reciprocity = nx.reciprocity(DG, 2)
|
|
30
|
-
assert reciprocity == 0.6666666666666666
|
|
31
|
-
|
|
32
|
-
# test for reciprocity for an isolated node
|
|
33
|
-
def test_reciprocity_graph_isolated_nodes(self):
|
|
34
|
-
with pytest.raises(nx.NetworkXError):
|
|
35
|
-
DG = nx.DiGraph([(1, 2)])
|
|
36
|
-
DG.add_node(4)
|
|
37
|
-
nx.reciprocity(DG, 4)
|