library single_library_test;

import 'dart:io'; 

import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';

import '../lib/docgen.dart';

main() {
  group('Generate docs for', () {
    test('one simple file.', () {
      var temporaryDir = new Directory('single_library').createTempSync();
      var fileName = path.join(temporaryDir.path, 'temp.dart');
      var file = new File(fileName);
      file.writeAsStringSync('''
  library test;
  /**
   * Doc comment for class [A].
   * 
   * Multiline Test
   */
  /*
   * Normal comment for class A.
   */
  class A {
    
    int _someNumber;
    
    A() {
      _someNumber = 12;
    }
    
    /**
     * Test for linking to parameter [A]
     */
    void doThis(int A) {
      print(A);
    }
  }
  
  main() {
    A a = new A();
    a.doThis(5);
  }
      ''');
      
      getMirrorSystem([fileName])
        .then(expectAsync1((mirrorSystem) {
          var testLibraryUri = new Uri(scheme: 'file', 
              path: path.absolute(fileName));
          var library = generateLibrary(mirrorSystem.libraries[testLibraryUri]);
          expect(library is Library, isTrue);
          
          var classTypes = library.classes;
          expect(classTypes is ClassGroup, isTrue);
          
          var classes = [];
          classes.addAll(classTypes.classes.values);
          classes.addAll(classTypes.errors.values);
          expect(classes.every((e) => e is Class), isTrue);
          
          expect(classTypes.typedefs.values.every((e) => e is Typedef), isTrue);
          
          var classMethodTypes = [];
          classes.forEach((e) {
            classMethodTypes.add(e.methods);
            classMethodTypes.add(e.inheritedMethods);
          });
          expect(classMethodTypes.every((e) => e is MethodGroup), isTrue);

          var classMethods = [];
          classMethodTypes.forEach((e) {
            classMethods.addAll(e.setters.values);
            classMethods.addAll(e.getters.values);
            classMethods.addAll(e.constructors.values);
            classMethods.addAll(e.operators.values);
            classMethods.addAll(e.regularMethods.values);
          });
          expect(classMethods.every((e) => e is Method), isTrue);
          
          var methodParameters = [];
          classMethods.forEach((e) { 
            methodParameters.addAll(e.parameters.values);
          });
          expect(methodParameters.every((e) => e is Parameter), isTrue);
          
          var functionTypes = library.functions;
          expect(functionTypes is MethodGroup, isTrue);
          
          var functions = [];
          functions.addAll(functionTypes.setters.values);
          functions.addAll(functionTypes.getters.values);
          functions.addAll(functionTypes.constructors.values);
          functions.addAll(functionTypes.operators.values);
          functions.addAll(functionTypes.regularMethods.values);
          expect(functions.every((e) => e is Method), isTrue);
          
          var functionParameters = [];
          functions.forEach((e) {
            functionParameters.addAll(e.parameters.values); 
          });
          expect(functionParameters.every((e) => e is Parameter), isTrue);
    
          var variables = library.variables.values;
          expect(variables.every((e) => e is Variable), isTrue);
          
          /// Testing fixReference 
          // Testing Doc comment for class [A].
          var libraryMirror = mirrorSystem.libraries[testLibraryUri];
          var classMirror = libraryMirror.classes.values.first;
          var classDocComment = fixReference('A', libraryMirror, 
              classMirror, null).children.first.text;
          expect(classDocComment == 'test.A', isTrue);
          
          // Test for linking to parameter [A]
          var methodMirror = classMirror.methods['doThis'];
          var methodParameterDocComment = fixReference('A', libraryMirror,
              classMirror, methodMirror).children.first.text;
          expect(methodParameterDocComment == 'test.A.doThis#A', isTrue);
          
          // Testing trying to refer to doThis function
          var methodDocComment = fixReference('doThis', libraryMirror, 
              classMirror, methodMirror).children.first.text;
          expect(methodDocComment == 'test.A.doThis', isTrue);
          
          // Testing something with no reference
          var libraryDocComment = fixReference('foobar', libraryMirror,
              classMirror, methodMirror).children.first.text;
          expect(libraryDocComment == 'foobar', isTrue);
        })).whenComplete(() => temporaryDir.deleteSync(recursive: true));
    });
  });
}
