KiCad PCB EDA Suite
Loading...
Searching...
No Matches
downgrade_oracle_utils.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <fstream>
23#include <algorithm>
24#include <initializer_list>
25#include <set>
26#include <stdexcept>
27#include <string>
28#include <vector>
29
30#include <wx/image.h>
31#include <wx/imagpng.h>
32#include <wx/mstream.h>
33
34#include <boost/test/unit_test.hpp>
36#include <downgrade_scan.h>
37#include <downgrade_target.h>
38
39namespace KI_TEST
40{
41
42inline const DOWNGRADE_TARGET& RequireDowngradeTarget( const wxString& aId )
43{
44 const DOWNGRADE_TARGET* target = FindDowngradeTarget( aId );
45
46 if( !target )
47 throw std::runtime_error( "Required downgrade test target is missing: " + aId.ToStdString() );
48
49 return *target;
50}
51
52
63
64
65inline void CheckTransformCoverage( const COMPATIBILITY_REPORT& aReport, int aTargetVersion,
66 std::initializer_list<EXPECTED_DOWNGRADE_FEATURE> aFeatures,
67 bool aDropInsteadOfApproximate )
68{
69 BOOST_REQUIRE( !aReport.IsBlocked() );
70 BOOST_REQUIRE( aReport.IsLossy() );
71 size_t expectedRows = 0;
72
73 for( const EXPECTED_DOWNGRADE_FEATURE& feature : aFeatures )
74 {
75 BOOST_TEST_CONTEXT( feature.m_name.ToStdString() )
76 {
77 const auto entry = std::find_if( aReport.Entries().begin(), aReport.Entries().end(),
78 [&]( const COMPAT_ENTRY& aEntry )
79 {
80 return aEntry.m_feature == feature.m_name;
81 } );
82
83 if( aTargetVersion >= feature.m_introducedIn )
84 {
85 BOOST_CHECK( entry == aReport.Entries().end() );
86 continue;
87 }
88
89 ++expectedRows;
90 BOOST_REQUIRE_MESSAGE( entry != aReport.Entries().end(), "Transform fixture no longer exercises feature" );
91 BOOST_CHECK_GT( entry->m_count, 0 );
92 const DOWNGRADE_BUCKET expectedBucket = aDropInsteadOfApproximate
93 && feature.m_bucket == DOWNGRADE_BUCKET::LOWER
94 && !feature.m_keepUnderOmitPolicy
96 : feature.m_bucket;
97 BOOST_CHECK( entry->m_bucket == expectedBucket );
98 }
99 }
100
101 BOOST_CHECK_EQUAL( aReport.Entries().size(), expectedRows );
102}
103
104
107inline wxMemoryBuffer MakePngWithFractionalPixelsPerCm()
108{
109 if( !wxImage::FindHandler( wxBITMAP_TYPE_PNG ) )
110 wxImage::AddHandler( new wxPNGHandler );
111
112 wxImage img( 4, 4 );
113 img.SetOption( wxIMAGE_OPTION_RESOLUTIONX, 96 );
114 img.SetOption( wxIMAGE_OPTION_RESOLUTIONY, 96 );
115 img.SetOption( wxIMAGE_OPTION_RESOLUTIONUNIT, wxIMAGE_RESOLUTION_INCHES );
116
117 wxMemoryOutputStream out;
118 img.SaveFile( out, wxBITMAP_TYPE_PNG );
119
120 wxMemoryBuffer buf;
121 buf.SetBufSize( out.GetSize() );
122 out.CopyTo( buf.GetData(), out.GetSize() );
123 buf.SetDataLen( out.GetSize() );
124
125 return buf;
126}
127
128
130inline std::set<std::string> LoadTokenSet( const std::string& aFileName )
131{
132 std::set<std::string> tokens;
133 std::ifstream file( aFileName );
134 std::string line;
135
136 while( std::getline( file, line ) )
137 {
138 while( !line.empty() && ( line.back() == '\r' || line.back() == ' ' ) )
139 line.pop_back();
140
141 if( !line.empty() )
142 tokens.insert( line );
143 }
144
145 return tokens;
146}
147
148
151inline std::vector<std::string> UnknownSexprHeads( const std::string& aContent, const std::set<std::string>& aKnown,
152 const std::set<std::string>& aHarmless = {} )
153{
154 std::vector<std::string> unknown;
155
156 for( const std::string& head : ExtractSexprNodeHeads( StripSexprStrings( aContent ) ) )
157 {
158 if( !aKnown.count( head ) && !aHarmless.count( head ) )
159 unknown.push_back( head );
160 }
161
162 return unknown;
163}
164
165} // namespace KI_TEST
What an export to a given target will keep, approximate, drop, or block.
bool IsLossy() const
True if anything is approximated or dropped. This is what triggers the lossy warning.
bool IsBlocked() const
True if some feature makes the target impossible. The user cannot export anyway.
const std::vector< COMPAT_ENTRY > & Entries() const
DOWNGRADE_BUCKET
What happens to a feature when we export to an older KiCad.
@ LOWER
Approximated down to a simpler equivalent.
@ DROP
No equivalent, left out.
std::string StripSexprStrings(const std::string &aText)
Drop quoted strings so a token inside a text value cannot cause a false refusal.
std::set< std::string > ExtractSexprNodeHeads(const std::string &aText)
Every lowercase node head in the text, e.g. for checking output against a release keyword set.
const DOWNGRADE_TARGET * FindDowngradeTarget(const wxString &aNameOrId)
Match a user-supplied target string against name or stable id, case-insensitively.
Test utilities for timestamps.
std::set< std::string > LoadTokenSet(const std::string &aFileName)
Read a release keyword file from qa/data/downgrade, one token per line.
void CheckTransformCoverage(const COMPATIBILITY_REPORT &aReport, int aTargetVersion, std::initializer_list< EXPECTED_DOWNGRADE_FEATURE > aFeatures, bool aDropInsteadOfApproximate)
const DOWNGRADE_TARGET & RequireDowngradeTarget(const wxString &aId)
wxMemoryBuffer MakePngWithFractionalPixelsPerCm()
A tiny PNG whose embedded resolution gives a fractional pixels/cm, so the legacy truncating PPI diffe...
std::vector< std::string > UnknownSexprHeads(const std::string &aContent, const std::set< std::string > &aKnown, const std::set< std::string > &aHarmless={})
Every node head in the serialized text that is not in the known or harmless sets.
One line in the compatibility report.
An older KiCad release we can export a project back to.
bool m_keepUnderOmitPolicy
Mirrors BOARD_RULE::m_keepUnderOmitPolicy.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")