tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lib.rs (8795B)


      1 use l10nregistry::env::ErrorReporter;
      2 use l10nregistry::errors::L10nRegistryError;
      3 use l10nregistry::fluent::FluentBundle;
      4 use l10nregistry::registry::BundleAdapter;
      5 use l10nregistry::registry::L10nRegistry;
      6 use l10nregistry::source::FileFetcher;
      7 use async_trait::async_trait;
      8 use fluent_fallback::{env::LocalesProvider, types::ResourceId};
      9 use fluent_testing::MockFileSystem;
     10 use std::cell::RefCell;
     11 use std::rc::Rc;
     12 use unic_langid::LanguageIdentifier;
     13 
     14 pub mod solver;
     15 
     16 pub struct RegistrySetup {
     17    pub name: String,
     18    pub file_sources: Vec<FileSource>,
     19    pub locales: Vec<LanguageIdentifier>,
     20 }
     21 
     22 pub struct FileSource {
     23    pub name: String,
     24    pub metasource: String,
     25    pub locales: Vec<LanguageIdentifier>,
     26    pub path_scheme: String,
     27 }
     28 
     29 #[derive(Clone)]
     30 pub struct MockBundleAdapter;
     31 
     32 impl BundleAdapter for MockBundleAdapter {
     33    fn adapt_bundle(&self, _bundle: &mut FluentBundle) {}
     34 }
     35 
     36 impl FileSource {
     37    pub fn new<S>(
     38        name: S,
     39        metasource: Option<S>,
     40        locales: Vec<LanguageIdentifier>,
     41        path_scheme: S,
     42    ) -> Self
     43    where
     44        S: ToString,
     45    {
     46        let metasource = match metasource {
     47            Some(s) => s.to_string(),
     48            None => String::default(),
     49        };
     50 
     51        Self {
     52            name: name.to_string(),
     53            metasource,
     54            locales,
     55            path_scheme: path_scheme.to_string(),
     56        }
     57    }
     58 }
     59 
     60 impl RegistrySetup {
     61    pub fn new(
     62        name: &str,
     63        file_sources: Vec<FileSource>,
     64        locales: Vec<LanguageIdentifier>,
     65    ) -> Self {
     66        Self {
     67            name: name.to_string(),
     68            file_sources,
     69            locales,
     70        }
     71    }
     72 }
     73 
     74 impl From<fluent_testing::scenarios::structs::Scenario> for RegistrySetup {
     75    fn from(s: fluent_testing::scenarios::structs::Scenario) -> Self {
     76        Self {
     77            name: s.name,
     78            file_sources: s
     79                .file_sources
     80                .into_iter()
     81                .map(|source| {
     82                    FileSource::new(
     83                        source.name,
     84                        None,
     85                        source
     86                            .locales
     87                            .into_iter()
     88                            .map(|l| l.parse().unwrap())
     89                            .collect(),
     90                        source.path_scheme,
     91                    )
     92                })
     93                .collect(),
     94            locales: s
     95                .locales
     96                .into_iter()
     97                .map(|loc| loc.parse().unwrap())
     98                .collect(),
     99        }
    100    }
    101 }
    102 
    103 impl From<&fluent_testing::scenarios::structs::Scenario> for RegistrySetup {
    104    fn from(s: &fluent_testing::scenarios::structs::Scenario) -> Self {
    105        Self {
    106            name: s.name.clone(),
    107            file_sources: s
    108                .file_sources
    109                .iter()
    110                .map(|source| {
    111                    FileSource::new(
    112                        source.name.clone(),
    113                        None,
    114                        source.locales.iter().map(|l| l.parse().unwrap()).collect(),
    115                        source.path_scheme.clone(),
    116                    )
    117                })
    118                .collect(),
    119            locales: s.locales.iter().map(|loc| loc.parse().unwrap()).collect(),
    120        }
    121    }
    122 }
    123 
    124 #[derive(Default)]
    125 struct InnerFileFetcher {
    126    fs: MockFileSystem,
    127 }
    128 
    129 #[derive(Clone)]
    130 pub struct TestFileFetcher {
    131    inner: Rc<InnerFileFetcher>,
    132 }
    133 
    134 impl TestFileFetcher {
    135    pub fn new() -> Self {
    136        Self {
    137            inner: Rc::new(InnerFileFetcher::default()),
    138        }
    139    }
    140 
    141    pub fn get_test_file_source(
    142        &self,
    143        name: &str,
    144        metasource: Option<String>,
    145        locales: Vec<LanguageIdentifier>,
    146        path: &str,
    147    ) -> l10nregistry::source::FileSource {
    148        l10nregistry::source::FileSource::new(
    149            name.to_string(),
    150            metasource,
    151            locales,
    152            path.to_string(),
    153            Default::default(),
    154            self.clone(),
    155        )
    156    }
    157 
    158    pub fn get_test_file_source_with_index(
    159        &self,
    160        name: &str,
    161        metasource: Option<String>,
    162        locales: Vec<LanguageIdentifier>,
    163        path: &str,
    164        index: Vec<&str>,
    165    ) -> l10nregistry::source::FileSource {
    166        l10nregistry::source::FileSource::new_with_index(
    167            name.to_string(),
    168            metasource,
    169            locales,
    170            path.to_string(),
    171            Default::default(),
    172            self.clone(),
    173            index.into_iter().map(|s| s.to_string()).collect(),
    174        )
    175    }
    176 
    177    pub fn get_registry<S>(&self, setup: S) -> L10nRegistry<TestEnvironment, MockBundleAdapter>
    178    where
    179        S: Into<RegistrySetup>,
    180    {
    181        self.get_registry_and_environment(setup).1
    182    }
    183 
    184    pub fn get_registry_and_environment<S>(
    185        &self,
    186        setup: S,
    187    ) -> (
    188        TestEnvironment,
    189        L10nRegistry<TestEnvironment, MockBundleAdapter>,
    190    )
    191    where
    192        S: Into<RegistrySetup>,
    193    {
    194        let setup: RegistrySetup = setup.into();
    195        let provider = TestEnvironment::new(setup.locales);
    196 
    197        let reg = L10nRegistry::with_provider(provider.clone());
    198        let sources = setup
    199            .file_sources
    200            .into_iter()
    201            .map(|source| {
    202                let mut s = self.get_test_file_source(
    203                    &source.name,
    204                    Some(source.metasource),
    205                    source.locales,
    206                    &source.path_scheme,
    207                );
    208                s.set_reporter(provider.clone());
    209                s
    210            })
    211            .collect();
    212        reg.register_sources(sources).unwrap();
    213        (provider, reg)
    214    }
    215 
    216    pub fn get_registry_and_environment_with_adapter<S, B>(
    217        &self,
    218        setup: S,
    219        bundle_adapter: B,
    220    ) -> (TestEnvironment, L10nRegistry<TestEnvironment, B>)
    221    where
    222        S: Into<RegistrySetup>,
    223        B: BundleAdapter,
    224    {
    225        let setup: RegistrySetup = setup.into();
    226        let provider = TestEnvironment::new(setup.locales);
    227 
    228        let mut reg = L10nRegistry::with_provider(provider.clone());
    229        let sources = setup
    230            .file_sources
    231            .into_iter()
    232            .map(|source| {
    233                let mut s = self.get_test_file_source(
    234                    &source.name,
    235                    None,
    236                    source.locales,
    237                    &source.path_scheme,
    238                );
    239                s.set_reporter(provider.clone());
    240                s
    241            })
    242            .collect();
    243        reg.register_sources(sources).unwrap();
    244        reg.set_bundle_adapter(bundle_adapter)
    245            .expect("Failed to set bundle adapter.");
    246        (provider, reg)
    247    }
    248 }
    249 
    250 #[async_trait(?Send)]
    251 impl FileFetcher for TestFileFetcher {
    252    fn fetch_sync(&self, resource_id: &ResourceId) -> std::io::Result<String> {
    253        self.inner.fs.get_test_file_sync(&resource_id.value)
    254    }
    255 
    256    async fn fetch(&self, resource_id: &ResourceId) -> std::io::Result<String> {
    257        self.inner.fs.get_test_file_async(&resource_id.value).await
    258    }
    259 }
    260 
    261 pub enum ErrorStrategy {
    262    Panic,
    263    Report,
    264    Nothing,
    265 }
    266 
    267 pub struct InnerTestEnvironment {
    268    locales: Vec<LanguageIdentifier>,
    269    errors: Vec<L10nRegistryError>,
    270    error_strategy: ErrorStrategy,
    271 }
    272 
    273 #[derive(Clone)]
    274 pub struct TestEnvironment {
    275    inner: Rc<RefCell<InnerTestEnvironment>>,
    276 }
    277 
    278 impl TestEnvironment {
    279    pub fn new(locales: Vec<LanguageIdentifier>) -> Self {
    280        Self {
    281            inner: Rc::new(RefCell::new(InnerTestEnvironment {
    282                locales,
    283                errors: vec![],
    284                error_strategy: ErrorStrategy::Report,
    285            })),
    286        }
    287    }
    288 
    289    pub fn set_locales(&self, locales: Vec<LanguageIdentifier>) {
    290        self.inner.borrow_mut().locales = locales;
    291    }
    292 
    293    pub fn errors(&self) -> Vec<L10nRegistryError> {
    294        self.inner.borrow().errors.clone()
    295    }
    296 
    297    pub fn clear_errors(&self) {
    298        self.inner.borrow_mut().errors.clear()
    299    }
    300 }
    301 
    302 impl LocalesProvider for TestEnvironment {
    303    type Iter = std::vec::IntoIter<LanguageIdentifier>;
    304 
    305    fn locales(&self) -> Self::Iter {
    306        self.inner.borrow().locales.clone().into_iter()
    307    }
    308 }
    309 
    310 impl ErrorReporter for TestEnvironment {
    311    fn report_errors(&self, errors: Vec<L10nRegistryError>) {
    312        match self.inner.borrow().error_strategy {
    313            ErrorStrategy::Panic => {
    314                panic!("Errors: {:#?}", errors);
    315            }
    316            ErrorStrategy::Report => {
    317                #[cfg(test)] // Don't let printing affect benchmarks
    318                eprintln!("Errors: {:#?}", errors);
    319            }
    320            ErrorStrategy::Nothing => {}
    321        }
    322        self.inner.borrow_mut().errors.extend(errors);
    323    }
    324 }